目录
I 背景
#mermaid-svg-MLwNA9lWgRhostMR {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-MLwNA9lWgRhostMR .error-icon{fill:#552222;}#mermaid-svg-MLwNA9lWgRhostMR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MLwNA9lWgRhostMR .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-MLwNA9lWgRhostMR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MLwNA9lWgRhostMR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MLwNA9lWgRhostMR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MLwNA9lWgRhostMR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MLwNA9lWgRhostMR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MLwNA9lWgRhostMR .marker.cross{stroke:#333333;}#mermaid-svg-MLwNA9lWgRhostMR svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MLwNA9lWgRhostMR .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MLwNA9lWgRhostMR .cluster-label text{fill:#333;}#mermaid-svg-MLwNA9lWgRhostMR .cluster-label span{color:#333;}#mermaid-svg-MLwNA9lWgRhostMR .label text,#mermaid-svg-MLwNA9lWgRhostMR span{fill:#333;color:#333;}#mermaid-svg-MLwNA9lWgRhostMR .node rect,#mermaid-svg-MLwNA9lWgRhostMR .node circle,#mermaid-svg-MLwNA9lWgRhostMR .node ellipse,#mermaid-svg-MLwNA9lWgRhostMR .node polygon,#mermaid-svg-MLwNA9lWgRhostMR .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MLwNA9lWgRhostMR .node .label{text-align:center;}#mermaid-svg-MLwNA9lWgRhostMR .node.clickable{cursor:pointer;}#mermaid-svg-MLwNA9lWgRhostMR .arrowheadPath{fill:#333333;}#mermaid-svg-MLwNA9lWgRhostMR .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MLwNA9lWgRhostMR .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MLwNA9lWgRhostMR .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-MLwNA9lWgRhostMR .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-MLwNA9lWgRhostMR .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MLwNA9lWgRhostMR .cluster text{fill:#333;}#mermaid-svg-MLwNA9lWgRhostMR .cluster span{color:#333;}#mermaid-svg-MLwNA9lWgRhostMR div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MLwNA9lWgRhostMR :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
耗时费力
漏打少打
打包过程不透明
项目打包现状
微服务众多
痛点
微服务间相互依赖
多人多分支协同开发
- 众多相互依赖的微服务打包需严格保证打包顺序,前置服务未打包完成的情况下,后置服务启动打包即容易出现漏打;或者前置服务已打包,后置服务部分打包的情况即出现少打。依靠每个开发人员自行甄别控制,一方面过于繁琐,另一方面也增加新员工培训成本。
- 当前的测试环境打包即使在提供了固定的打包机、多人多地点同时协同开发的情况下,整个打包过程过于封闭不透明,同时也存在打包机资源挤退、抢占或重复打包的情况。
- 打包机打包方式过于原始,依然采用的是IDEA打包,对于多工程服务情况下,同时打开过多的IDEA数量对打包机的资源消耗过大,虽然能直观的看到代码以及修订过程,整体的打包体验弊大于利。
基于以上现状,在项目里推出Jenkins自动化打包部署方案,带来以下改观:
#mermaid-svg-opcYAvXa4MyXk69D {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-opcYAvXa4MyXk69D .error-icon{fill:#552222;}#mermaid-svg-opcYAvXa4MyXk69D .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-opcYAvXa4MyXk69D .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-opcYAvXa4MyXk69D .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-opcYAvXa4MyXk69D .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-opcYAvXa4MyXk69D .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-opcYAvXa4MyXk69D .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-opcYAvXa4MyXk69D .marker{fill:#333333;stroke:#333333;}#mermaid-svg-opcYAvXa4MyXk69D .marker.cross{stroke:#333333;}#mermaid-svg-opcYAvXa4MyXk69D svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-opcYAvXa4MyXk69D .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-opcYAvXa4MyXk69D .cluster-label text{fill:#333;}#mermaid-svg-opcYAvXa4MyXk69D .cluster-label span{color:#333;}#mermaid-svg-opcYAvXa4MyXk69D .label text,#mermaid-svg-opcYAvXa4MyXk69D span{fill:#333;color:#333;}#mermaid-svg-opcYAvXa4MyXk69D .node rect,#mermaid-svg-opcYAvXa4MyXk69D .node circle,#mermaid-svg-opcYAvXa4MyXk69D .node ellipse,#mermaid-svg-opcYAvXa4MyXk69D .node polygon,#mermaid-svg-opcYAvXa4MyXk69D .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-opcYAvXa4MyXk69D .node .label{text-align:center;}#mermaid-svg-opcYAvXa4MyXk69D .node.clickable{cursor:pointer;}#mermaid-svg-opcYAvXa4MyXk69D .arrowheadPath{fill:#333333;}#mermaid-svg-opcYAvXa4MyXk69D .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-opcYAvXa4MyXk69D .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-opcYAvXa4MyXk69D .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-opcYAvXa4MyXk69D .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-opcYAvXa4MyXk69D .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-opcYAvXa4MyXk69D .cluster text{fill:#333;}#mermaid-svg-opcYAvXa4MyXk69D .cluster span{color:#333;}#mermaid-svg-opcYAvXa4MyXk69D div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-opcYAvXa4MyXk69D :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
web页面访问
前置服务打包后自动触发后置服务
前置服务打包过程中阻止下游项目构建
自由指定JDK,git分支,maven等打包依赖要素
扩展插件支持gitlab回调打包,windows linux命令执行,构建物上传等
过程直观
改观
依赖触发
依赖阻碍
灵活配置
灵活扩展
II Jenkins安装部署
2.1.Jenkins官网下载安装包
最新版本:
历史版本:
对应版本与JDK支持关系:
2.2.Jenkins安装
此处以【2.426.1 LTS Windows】版本为例
#mermaid-svg-Ua9qZhXFZDROctiI {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Ua9qZhXFZDROctiI .error-icon{fill:#552222;}#mermaid-svg-Ua9qZhXFZDROctiI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ua9qZhXFZDROctiI .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-Ua9qZhXFZDROctiI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ua9qZhXFZDROctiI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ua9qZhXFZDROctiI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ua9qZhXFZDROctiI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ua9qZhXFZDROctiI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ua9qZhXFZDROctiI .marker.cross{stroke:#333333;}#mermaid-svg-Ua9qZhXFZDROctiI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ua9qZhXFZDROctiI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Ua9qZhXFZDROctiI .cluster-label text{fill:#333;}#mermaid-svg-Ua9qZhXFZDROctiI .cluster-label span{color:#333;}#mermaid-svg-Ua9qZhXFZDROctiI .label text,#mermaid-svg-Ua9qZhXFZDROctiI span{fill:#333;color:#333;}#mermaid-svg-Ua9qZhXFZDROctiI .node rect,#mermaid-svg-Ua9qZhXFZDROctiI .node circle,#mermaid-svg-Ua9qZhXFZDROctiI .node ellipse,#mermaid-svg-Ua9qZhXFZDROctiI .node polygon,#mermaid-svg-Ua9qZhXFZDROctiI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ua9qZhXFZDROctiI .node .label{text-align:center;}#mermaid-svg-Ua9qZhXFZDROctiI .node.clickable{cursor:pointer;}#mermaid-svg-Ua9qZhXFZDROctiI .arrowheadPath{fill:#333333;}#mermaid-svg-Ua9qZhXFZDROctiI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Ua9qZhXFZDROctiI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Ua9qZhXFZDROctiI .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-Ua9qZhXFZDROctiI .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-Ua9qZhXFZDROctiI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Ua9qZhXFZDROctiI .cluster text{fill:#333;}#mermaid-svg-Ua9qZhXFZDROctiI .cluster span{color:#333;}#mermaid-svg-Ua9qZhXFZDROctiI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Ua9qZhXFZDROctiI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
Jenkins官网下载
打包工程所在
Java运行环境
此处复用了IDEA内的Maven,也可指定其他版本
Setting文件指定
Jenkins2.426.1安装准备
jenkins.war
JENKINS_HOME工作目录
JDK11
Maven
本地仓库
2.2.1 启动Jenkins流程
Created with Raphaël 2.3.0
第一次启动
获取初始密码
安装插件
插件安装成功
添加管理员用户
实例配置
结束
修改插件中心地址
yes
no
第一次启动
Win+R 打开cmd窗口
java -Xms4096m -Xmx8192m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=8192m -DJENKINS_HOME=D:\SOFT\jenkins2.426.1-dev\jenkins -jar D:\SOFT\jenkins2.426.1-dev\jenkins.war --httpPort=8090
-DJENKINS_HOME 该参数指定Jenkins工作目录,打包工程会存放该目录
--httpPort 指定启动端口(默认为:8080)
启动成功后终端会打印出初始密码
访问Jenkins Web端(http://localhost:8090 端口如果未指定默认用8080)
初始密码也可通过配置文件中获取,路径为:
%JENKINS_HOME\secrets\initialAdminPassword
安装插件,可选择按推荐的安装也可选择自定义安装,后续也可根据需要在插件中心中安装插件
注:等待所有插件安装结束后会自动跳转页面,若安装插件失败,多半是由于插件中心地址访问超时,可修改为国内地址,重新安装即可
--修改插件中心地址
--配置文件目录:%JENKINS_HOME\hudson.model.UpdateCenter.xml
<url>http://mirror.xmission.com/jenkins/updates/update-center.json</url>
创建管理员用户
实例配置
配置好之后的jenkins页面
2.2.2 安装个性化插件
大家打开基础版的Jenkins后就会发现,虽然Jenkins安装成功了,但似乎还不太满足项目构建的需要,当然了Jenkins提供了很多个性化的插件,我们可以根据需要自由搭配来满足不同场景的构建需求
比如:我想新建一个Maven的构建,基础版是没有该选项的,那么我们可以在插件中心去安装该类插件
打开插件中心
此处罗列常用的功能插件
插件名称插件功能Maven Integration构建Maven项目JDK Parameter当工程jdk与jenkins所需jdk不一致时,可单独指定打包工程所用java环境Publish Over SSH用于构建成功后发布物上传Build Authorization Token Root用于代码管理平台,如gitlab上配置回调钩子,在代码更新后调用触发jenkins构建……
III 项目打包配置
#mermaid-svg-GeMDY5roQgkouvGh {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GeMDY5roQgkouvGh .error-icon{fill:#552222;}#mermaid-svg-GeMDY5roQgkouvGh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GeMDY5roQgkouvGh .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-GeMDY5roQgkouvGh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GeMDY5roQgkouvGh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GeMDY5roQgkouvGh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GeMDY5roQgkouvGh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GeMDY5roQgkouvGh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GeMDY5roQgkouvGh .marker.cross{stroke:#333333;}#mermaid-svg-GeMDY5roQgkouvGh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GeMDY5roQgkouvGh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-GeMDY5roQgkouvGh .cluster-label text{fill:#333;}#mermaid-svg-GeMDY5roQgkouvGh .cluster-label span{color:#333;}#mermaid-svg-GeMDY5roQgkouvGh .label text,#mermaid-svg-GeMDY5roQgkouvGh span{fill:#333;color:#333;}#mermaid-svg-GeMDY5roQgkouvGh .node rect,#mermaid-svg-GeMDY5roQgkouvGh .node circle,#mermaid-svg-GeMDY5roQgkouvGh .node ellipse,#mermaid-svg-GeMDY5roQgkouvGh .node polygon,#mermaid-svg-GeMDY5roQgkouvGh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GeMDY5roQgkouvGh .node .label{text-align:center;}#mermaid-svg-GeMDY5roQgkouvGh .node.clickable{cursor:pointer;}#mermaid-svg-GeMDY5roQgkouvGh .arrowheadPath{fill:#333333;}#mermaid-svg-GeMDY5roQgkouvGh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GeMDY5roQgkouvGh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GeMDY5roQgkouvGh .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-GeMDY5roQgkouvGh .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-GeMDY5roQgkouvGh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GeMDY5roQgkouvGh .cluster text{fill:#333;}#mermaid-svg-GeMDY5roQgkouvGh .cluster span{color:#333;}#mermaid-svg-GeMDY5roQgkouvGh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GeMDY5roQgkouvGh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
当前项目构建所需配置
Maven配置
jdk配置
SSH配置
3.1 工具配置
Maven配置
菜单路径:Dashboard\Manage Jenkins\Tools
JDK配置
菜单路径:Dashboard\Manage Jenkins\Tools
SSH配置
菜单路径:Dashboard\Manage Jenkins\System(该配置有所不同,在System下)
3.2 新增构建流程
Created with Raphaël 2.3.0
开始
新增Maven构建项目aaa
添加jdk参数
修改并发构建参数
添加git代码仓库及用户密码并指定打包分支
去掉pom项目依赖检查
指定pom.xml文件位置
添加构建后windows上执行脚本
新增构建后SSH上传配置
新增构建后触发项目
结束
新增Maven构建项目
指定JDK参数
修改并发构建参数
修改后在上游项目未构建完成时,如果主动触发构建下游项目会阻止构建放到等待队列里,避免做无用构建
添加Git信息
去掉POM项目依赖检查
此处去掉该检查的意义在于,如果勾选了该选项,Jenkins会自动根据pom文件识别出项目上下级依赖关系,会在上游项目构建完成后自动触发下游项目,去掉勾选后自行指定依赖,让Jenkins完全按照配置来打包
指定pom文件路径
默认在该工程目录的下一级,如果需要指定到更深层次pom,只需要添加工程目录下的路径即可
添加构建后windows执行脚本
由于我们已有部署平台,通过部署平台上传部署包,同时会更新数据库信息,直接上传到服务器目录并不会做登记,所以我们统一将发布物复制到固定目录,Jenkins可直接执行Windows batch command
添加构建后SSH上传
非必须,该处为演示
添加构建后触发其他项目
该处可指定上下游关系,上游项目构建成功后会触发下游项目打包
配置远程触发构建
该功能可以配合GitLab的Webhooks事件使用,在代码Push、Merge等场景下执行远程调用脚本,自动触发Jenkins构建
IV 操作流程
Created with Raphaël 2.3.0
开始
各分支协同开发
合并至各环境打版分支
是否配置Git远程触发?
Jenkins构建
应用部署
结束
手动触发
yes
no
V 使用总结
项目内已经持续使用了一个多月,目前两套频繁使用的测试环境都是通过Jenkins来构建,在满足使用的前提下也带来很多便捷,最主要的是开发人员习惯的改变,当然了凡事都有两面性,对于频繁打版的测试环境,也暴露出自动化构建的一些短板。
- 亮点
- 自动化构建的最大亮点,避免了繁琐的人工操作,配置好规则后Jenkins即会按照预设的方向运行
- 配置好各工程依赖规则后,Jenkins会进行构建校验,确保前置工程已构建完的情况下构建下游项目,避免重复无用的构建
- 整个构建过程对项目组内开发人员完全透明化,哪个工程什么时候构建了,成功还是失败,构建日志能查看失败原因,变更记录能查看本次构建的代码修订记录,工作空间里能查看构建的工程,甚至某个工程的某个构建是由于依赖自动触发还是哪个用户手动触发构建等等信息
- 支持视图化操作,提取常用工程,快捷操作
- 短板
- 构建透明化的同时带来的问题就是代码不透明,Jenkins是自动拉取Git代码,调用Maven打包,在频繁改动代码的测试环境很容易出现某个开发人员提交的代码影响了构建,离开了编译器的帮助的话不容易去定位问题,即使在Jenkins控制台输出了部分日志信息的情况下,出现问题后还得远程到Jenkins所在的服务器去排查代码,或者开发人员本地跑一遍构建
- 同以前的打包方式相比,Jenkins依然需要一个打包机服务器资源,同时为了保证构建的运行流畅,对服务器的内存、磁盘配置也有一定要求
亮点也好,短板也罢,Jenkins的设计初衷当然并非为了解决某一个项目的问题,亮点应该就是用对了场景,短板也应该还有其他的解决方案,局限我们的不是工具,而是思维。
版权归原作者 开黑店的胖船长 所有, 如有侵权,请联系我们删除。