把构建产物散落在各台服务器的 /data/app 目录下,时间一长就没人说得清线上跑的到底是哪次构建。做法不复杂:代码提交后由 Jenkins 打包,制品推给 Nexus 统一存,部署时从 Nexus 的制品列表里挑版本。这条链路配通之后,回滚就变成选一个旧版本号的事。
一、整体流程和 pom.xml
开发者用 SVN 或 Git 提交代码,每个发布版本都会更新 pom.xml 里的版本信息。Pipeline 读取这个 pom 拿到坐标,再用 Nexus 插件把 target 下的包传上去。上传完成后,Nexus 插件能在作业的 Web 界面上列出可下载的包地址,把这个地址交给 shell 脚本去 wget,部署动作就完成了。
pom 里真正被流水线用到的就四个字段:
groupId:业务名称简称artifactId:应用名称packaging:打包类型,pom/jar/warversion:版本信息

二、要装的插件
- Pipeline Utility Steps:提供
readMavenPom之类的能力,在当前工作目录中查找文件。 - Nexus Artifact Uploader:上传制品到制品库。
- Maven Artifact ChoiceListProvider (Nexus):读取制品库中的文件列表,用来做参数化构建的下拉选项。
- Nexus Platform:把 Nexus Repository Manager 和 Nexus Lifecycle 集成进 Jenkins 作业。
三、写 Pipeline
1. 先生成上传步骤的 DSL
不用手写,用 Jenkins 流水线语法生成器(Pipeline Syntax)配置一遍 nexusArtifactUploader,把生成的片段抄出来最省事。


上传要认证,先在凭据管理里加一个能连 Nexus 仓库的用户凭据。


加完之后记下这条凭据的唯一标识(ID),DSL 里的 credentialsId 就填它。


2. Pipeline 脚本
pipeline {
agent {
node { label 'master'}
}
#此处省略了多个步骤,直接上传制品的步骤
stages {
stage ('上传制品') {
steps {
script {
def nexusDate = sh returnStdout: true, script: 'date +%Y%m%d-%H%M%S'
def pom = readMavenPom file: './项目目录/pom.xml' #指定读取的pom文件路径
nexusArtifactUploader(artifacts: [[artifactId: "${pom.artifactId}",
classifier: '',
file: "./项目目录/target/${pom.artifactId}-${pom.version}.${pom.packaging}",
type: "${pom.packaging}"]],
credentialsId: 'Nexus凭据ID',
groupId: "${pom.groupId}",
nexusUrl: 'Nexus—IP:8090',
nexusVersion: 'nexus3',
protocol: 'http',
repository: "maven-releases(Nexus仓库名称)",
version: "${pom.version}-${nexusDate}-${BUILD_ID}")
}
}
}
stage('部署') {
steps {
script {
sh '''
ssh ${server_user}@${serverIP} "cd /data/app && wget ${Package}" #${Package}引用Job参数化构建传的值,然后该值传给由远程目标服务器上的脚本进行引用下载
'''
}
}
}
}
}
几个细节值得说明。版本号这里拼成 ${pom.version}-${nexusDate}-${BUILD_ID},加上时间戳和构建号是为了让同一次 pom 版本的多次构建互不覆盖,否则同名制品会被冲掉,回滚时找不回东西。部署阶段不在 Jenkins 节点上拷文件,而是把下载地址通过 ssh 交给目标机自己 wget,大包传输不把 Jenkins 当流量中转。
Nexus 那边要允许匿名下载,否则目标机上 wget 会直接报 401 被拒绝。

四、建 Job 和参数化选择制品
先建一个普通的 Pipeline 任务,把上面的脚本贴进去。

要做「构建时选制品版本」,就勾选参数化构建,参数类型用 Maven Artifact ChoiceListProvider (Nexus),它会把制品库里的文件列成下拉框;凭据沿用前面添加的那条,直接选即可。




之后每次发布就是触发这个 CD 任务、在下拉里选中要部署的版本号。

五、踩过的坑
nexusUrl只写 host:port,不要带http://前缀,协议由protocol字段单独指定。- 上传走 http 时,Nexus 前面挂过 https 反代的话要确认端口和跳转,不然插件报证书或连接错误。
- 匿名访问只对 release 仓库开,快照仓库或内部仓库别图省事一起放开。
wget下载没有校验步骤容易拿到半截包,脚本里加个存在性判断和大小检查再重启服务。- 制品列表越来越长之后,给 Nexus 配上清理策略,否则磁盘迟早被历史包占满。

















暂无评论内容