Jenkins 業務發版平滑上線實戰
背景簡介:
原來發版必須等到晚上10點訪問量最少的時候,期間服務中斷產生大量告警。為了不影響業務,現在需要修改jenkins使其平滑上線。具體操作步驟如下:
第一步:拉取git指定分支
Jenkins默認一個項目只能對應一個git分支來構建,通過git Parameter插件可以從項目中讀取GIT SCM 配置實現選擇分支或tag來構建項目。
pipeline {
parameters{
gitParameter(name: 'BRANCH_TAG',type: 'PT_BRANCH_TAG',defaultValue: 'master')
}
stage('gitpull') {
steps {
checkout([$class: 'GitSCM',
branches: [[name: "${params.BRANCH_TAG}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [],gitTool: 'Default',submoduleCfg: [],
userRemoteConfigs: [[url: 'http://xxx.git',credentialsId: 'xxx',]]
])
}}}
圖1-1 拉取指定分支
第二步:編譯
通過mvn編譯java代碼,將編譯后得到的jar包推送至各個服務器,其中servers_ips為各個服務器ip地址(如: servers_ips = ” 172.1.1.100 172.1.1.101”)。
script {
sh " mvn clean package -DskipTests " #編譯java項目代碼
for (server_ip in servers_ips.tokenize(' ')){
def remote = [:]
remote.name = root
remote.host = server_ip
remote.allowAnyHosts = true
withCredentials([sshUserPrivateKey(credentialsId:xxx,keyFileVariable:'identity',passphr aseVariable:'',usernameVariable:'userName')])
{
remote.user = userName
remote.identityFile = identity
sshPut remote: remote, from: "./target/xxx.jar", into: "/data/" #
將jar包推送至服務器
}}}
第三步:下線指定服務器
批量修改各個服務器上nginx配置,注釋upstream中指定的服務器,使其下線不提供服務,為之后新代碼上線做準備,在不影響業務的情況下平滑上線。
script {
for (server_ip2 in servers_ips.tokenize(' ')){
def remote = [:]
remote.name = root
remote.host = server_ip2
remote.allowAnyHosts = true
withCredentials([sshUserPrivateKey(credentialsId:xxx,keyFileVariable:'identity', passphraseVariable: '', usernameVariable: 'userName')]) {
remote.user = userName
remote.identityFile = identity
sshCommand remote: remote, command:"""
sed -i 's/.*'${指定服務器ip}'/#&/' /etc/nginx/conf.d/xxx.conf
nginx -s reload
"""
}}}
第四步:重啟服務運行新代碼
在剛下線的服務器上重啟java項目使其運行新的代碼。立即重啟會導致原有的連接返回5xx,所以在重啟之前sleep幾秒。
sleep 30
def remote = [:]
remote.name = root
remote.host = 指定服務器ip
remote.allowAnyHosts = true
withCredentials([sshUserPrivateKey(credentialsId: xxx, keyFileVariable: 'identity', passphraseVariable: '', usernameVariable: 'userName')]) {
remote.user = userName
remote.identityFile = identity
sshCommand remote: remote, command:"./prodservice.sh restart"
}
第五步:健康檢查
訪問該服務器后端提供的接口判斷是否可以提供服務。狀態碼為200即為健康即可上線提供服務,否則訪問3次之后拋出異常中斷Jenkins。服務啟動過程中進行檢查,jenkins會拋異常并中斷,這里需要加上異常處理繼續運行jenkins。
health_times=0
health_status = ""
while(health_times < 3){
try {
health_status = sh(script: "curl -I -m 10 -o /dev/null -s -w %{http_code} -d '' http://${server_ip}:8080/xxx", returnStdout: true).trim()
} catch(Exception e1) {
echo "服務沒起來" }
if ( health_status == '200' ){
echo "健康"
break
}else if ( health_times < 2) {
sleep 30
echo "不健康,再次嘗試檢測..."
}else{
error "不健康" }
health_times = health_times +1 }
第六步:上線指定服務器
通過健康檢查后,即可批量修改各個服務器上的nginx配置,使得該服務器上線提供服務。
for (server_ip2 in servers_ips.tokenize(' ')){
remote.name = root
remote.host = server_ip2
remote.allowAnyHosts = true
withCredentials([sshUserPrivateKey(credentialsId: ssh_credentialsId, keyFileVariable: 'identity', passphraseVariable: '', usernameVariable: 'userName')]) {
remote.user = userName
remote.identityFile = identity
sshCommand remote: remote, command:"""
sed -i 's/^#*\\(.*'${server_ip}'\\)/\\1/' /etc/nginx/conf.d/xxx.conf
nginx -s reload
"""
}}
第七步:檢查
在構建過程中循環curl服務,檢查是否會出現服務中斷的情況。下圖7-1為構建過程中的日志。
圖7-1 平滑上線過程
至此,Jenkins平滑上線完成。