随心一记

一二三四五,上山打老鼠


  • 首页

  • 归档

  • 标签
ywcsb

ywcsb

游戏可以不玩,小说不能不看。

153 日志
3 分类
42 标签
RSS
GitHub 知乎 随心一记
Links
  • 随心一记
  • 追梦人物的
  • MSDN

Jenkins 并行发布与回滚

发表于 2023-06-15 | 阅读 1996 | 分类于 系统运维 |

Jenkins 提供了强大的持续集成功能,本文将详细介绍如何利用 Jenkins 的 Pipeline 来实现并行发布与回滚。

环境准备

  1. Jenkins 安装并配置好环境
  2. 安装并配置好 Git 和 Maven
  3. 安装 Ansible

Jenkins Pipeline

在 Jenkins 中创建一个新的 Pipeline 任务,并在 Pipeline 脚本中粘贴以下代码。这个 Pipeline 实现了以下步骤:

  • 拉取代码
  • 编译代码
  • 备份文件
  • 发送通知到企业微信群
  • 并行执行 Ansible playbook 进行发版
  • 发版成功或失败后,发送通知到企业微信群
  • 功能解释
  • 环境变量设定(environment): 这部分定义了多个环境变量,包括应用名称、备份路径、备份名称、需要恢复的名称、Tomcat 路径、发布路径、本地路径、目标主机以及发版失败和成功的企业微信webhook通知。这些变量会在后面的步骤中使用。
  • 参数设定(parameters): 这部分定义了用户可以在 Jenkins UI 中输入的参数,包括 Git 分支、部署状态(发布或回滚)、版本号(用于回滚)和备注说明。
  • 发布或回滚(stage('发布或回滚')): 这个 stage 有两个 parallel stages,'Deploy' 和 'Rollback'。当用户选择 'Deploy' 时,脚本会拉取代码,编译代码并备份文件。当用户选择 'Rollback' 时,脚本将使用指定的版本号回滚到前一版本。
  • 发布(stage('publish')): 在这个 stage 中,首先会给相关人员发送发版通知,然后会暂停一段时间(默认为10分钟)让编辑老师保存数据。接着会并行执行发布操作,其中包括 "公司内部老师发版" 和 "外部老师发版"。
  • post 阶段(post): 在 build 成功或失败后,会发送对应的成功或失败的通知。
  • 发送通知函数(sendNotification): 这是一个辅助函数,用于向企业微信发送通知。接收一个消息和一个 webhook URL 作为参数,发送一个包含指定消息的 POST 请求到 webhook URL。
import java.util.Calendar
import java.text.SimpleDateFormat

pipeline {
    agent any
    environment  {
        // 应用名称
        VueName = "bxxAdmin"
        // 备份路路径
        BackupPath="/data/jenkins-backup/\${JOB_BASE_NAME}/${VueName}"
        // 备份的名称
        BackupName="${BackupPath}/${VueName}.war.\${BUILD_NUMBER}"
        // 需要恢复的名称 和 BackupName 应该是一样的
        BackupRollback="${BackupPath}/${VueName}.war.${params.Version}"
        // tomcat 路径
        TomcatPath="/usr/local/tomcat-admin-8081"
        // 发布路径
        DestPath="${TomcatPath}/webapps"
        //应用名称
        AppName="${VueName}"
        // 本地路径
        SrcPath="${WORKSPACE}/target/${VueName}.war"
        // 指定要发版的主机或在cmdb中创建的组
        TargetHost="bxx_admin_upload"
        // 发版失败的企业微信webhook通知
        FailureWebhookUrl="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=e0671a"
        // 发版成功的企业微信webhook通知
        SuccessWebhookUrl="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=d3c8"
    }
    parameters {
        gitParameter (
            branch: '', 
            branchFilter: 'origin/(.*)', 
            defaultValue: 'totest', 
            description: '分支变量', 
            name: 'branch', 
            quickFilterEnabled: false, 
            selectedValue: 'NONE', 
            sortMode: 'NONE', 
            tagFilter: '*', 
            type: 'GitParameterDefinition'
        )
        choice (
            choices: ['Deploy', 'Rollback'], 
            description: '''Deploy: 发布\nRollback: 回滚''', 
            name: 'Status'
        )
        string (
            description: '''----此项为回滚版本号,如果发布请忽略----''', 
            name: 'Version'
        )
        string (
            description: '''----备注说明----''', 
            name: 'remark'
        )
    }

    stages {
        stage('发布或回滚') {
            parallel {
                stage('Deploy') {
                    when {
                        expression {params.Status == 'Deploy'}
                        beforeOptions true
                    }
                    steps {
                        script {
                            stage ('拉取代码') {
                                git (
                                    branch: "${params.branch}",
                                    credentialsId: '7493a50b0867099e', 
                                    url: 'http://gitlab.sy.com/bxxjava/bxxAdmin2.git'
                                )
                            }
                            stage('编译代码') {
                                // One or more steps need to be included within the steps block.
                                echo "======status:${params.Status}========="
                                sh '''
                                    source /etc/profile
                                    sed -i 's#<bootclasspath>${java.home}/lib/rt.jar;${java.home}/lib/jce.jar</bootclasspath>#<bootclasspath>${java.home}/lib/rt.jar:${java.home}/lib/jce.jar</bootclasspath>#g' pom.xml
                                    mvn clean package
                                '''
                            }
                            stage ("备份文件") {
                                echo "======包到备份文件夹==============="
                                sh """
                                    if [ -d ${env.BackupPath} ];
                                    then
                                        echo "The files is already  exists "
                                    else
                                        mkdir -p  ${env.BackupPath}
                                    fi
                                    cp target/${env.VueName}.war  ${env.BackupName}
                                """
                                echo "deploy done!"
                            }
                        }
                    }
                }
                stage('Rollback') {
                    when {
                        expression {params.Status == 'Rollback'}
                        beforeOptions true
                    }
                    steps {
                        script {
                            if (params.Version == null || params.Version == '') {
                                error("当“Status ”为“Rollback”时,需要指定Version")
                            }
                        }
                        echo "======status:${params.Status}========"
                        echo "======build_id:${params.Version}======="
                        echo "==============回滚包放到原来的地方==================="
                        sh """\\cp -r ${env.BackupRollback} ./target/${env.VueName}.war"""
                    }
                }
            }
        }


        stage('publish') {
            steps {
                script {
                    // 设置暂停时间(分钟)
                    int pauseMinutes = 10
                    stage("发版通知到互联网3.0企业微信群") {
                        // 计算 pauseMinutes 分钟后的时间
                        Calendar futureTime = Calendar.getInstance()
                        futureTime.add(Calendar.MINUTE, pauseMinutes)

                        // 格式化时间
                        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm")
                        String formattedTime = sdf.format(futureTime.time)

                        // 发送企业微信通知
                        sendNotification("各位老师, 包学习后台将于 " + formattedTime + " 进行发版更新操作。请各位老师做好数据保存工作!", "${env.SuccessWebhookUrl}")
                    }

                    stage("暂停${pauseMinutes}分钟给编辑老师保存的时间") {
                        // 暂停 pauseMinutes 分钟
                        sleep(time: pauseMinutes * 60)  // 将分钟转换为秒
                    }
                    stage("并行发布") {
                        parallel(
                            "公司内部老师发版": {
                                ansiblePlaybook (
                                    colorized: true, 
                                    disableHostKeyChecking: true, 
                                    installation: 'ansible', 
                                    playbook: '/data/ansible/prod/java/bxx-admin-update.yml',
                                    extraVars: [
                                        dest_path: "${env.DestPath}",
                                        app_name: "${env.AppName}",
                                        src_path: "${env.SrcPath}",
                                        target_host: "${env.TargetHost}"
                                    ]
                                )
                            },
                            "外部老师发版": {
                            ansiblePlaybook (
                                colorized: true, 
                                disableHostKeyChecking: true, 
                                installation: 'ansible', 
                                playbook: '/data/ansible/prod/java/without-bxx-admin-update.yml',
                                extraVars: [
                                    dest_path: "${env.DestPath}",
                                    app_name: "${env.AppName}",
                                    src_path: "${env.SrcPath}"
                                ]
                            )
                            }
                        )
                    }
                }
            }
        }
    }
    post {
        success {
            script {
               sendNotification("各位老师,包学后台发布完成。", "${env.SuccessWebhookUrl}") 
            }
       }
       failure {
            script {
                sendNotification('包学习后台发版失败', "${env.FailureWebhookUrl}")
            }
       }
    }
}


def sendNotification(String message, String webhookUrl) {
    // def webhookUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_WEBHOOK_KEY"

    // 解析 Webhook URL 的 Key 部分
    def key = webhookUrl.split("=")[1]

    def payload = """
    {
        "msgtype": "text",
        "text": {
            "content": "${message.trim()}",
            "mentioned_list": ["@all"]
        }
    }
    """

    // 发送 HTTP POST 请求
    sh "curl -X POST -H 'Content-Type: application/json' -d '${payload}' '${webhookUrl}'"
}
觉得不错,支持一下!
geerniya WeChat Pay

微信打赏

geerniya Alipay

支付宝打赏

# Jenkins
systemctl 管理tomcat
git 操作

发表评论

共 0 条评论

    暂无评论
© 2018 - 2022 ywcsb
冀ICP备17022045号-1
Supported by 腾讯云