首页 > 其他分享 >Jenkins + Jenkinsfile + Go自动化Pipeline进行部署

Jenkins + Jenkinsfile + Go自动化Pipeline进行部署

时间:2023-06-22 15:00:55浏览次数:29  
标签:Pipeline remote APP echo env PATH Go Jenkins app

环境准备(因内容繁琐请自行搭建或问度娘)俺也会逐步更新相关文章
  • Jenkins环境
  • jenkins凭据管理
  • Pipeline语法
  • 安装钉钉插件并配置钉钉机器人
  • linux服务器
go本地目录结构(微服务)

Jenkins + Jenkinsfile + Go自动化Pipeline进行部署_go

服务器文件目录 /home/ubuntu

Jenkins + Jenkinsfile + Go自动化Pipeline进行部署_jenkins_02

Jenkinsfile文件

文件名为: Jenkinsfile

pipeline {

    agent any
 
    environment {
        // 一定要注意配置这里这里主要是用来加载启动配置文件,
        // 开发用dev,测试用test,生产用prod或者自定义也行
        conf_env = "test"
        // jenkins工作空间
        workspace_dir = "${env.WORKSPACE}"
        // 构建应用程序文件目录
        deploy_remote_dir = "/home/ubuntu/api/build"
        // deploy_remote_server是您的ip服务器地址
        deploy_remote_server = "您的ip服务器地址"
        // jenkins凭据管了的id,这里一定要注意安全,涉及到服务的安全问题
        deploy_remote_secret_key = "您的jenkins凭据管了的id"
        // 您的服务名称
        app_name = "common-consumer"
        // 所在目录
        app_code_dir = "common"
        // 部署目录
        app_upload_path = "${deploy_remote_dir}/${env.app_name}"
        // 日志文件
        app_log = "${deploy_remote_dir}/${env.app_name}.log"
        // jenkins您的git凭据id
        git_secret_key = "您的git凭据id"
        // 您的git仓库代码地址
        git_url = "您的git仓库代码地址"
        build_dir = "${env.workspace_dir}/src/${app_code_dir}/${app_name}"

        print = "'{print \$2}'"
        str_or = "|"
        dl = "\$"
    }

    parameters {
        choice(name: 'branch', choices: ['dev', 'test', 'master'], description: '分支构建')
    }
 
    stages {
        
        stage("git pull code") {
            steps {
                echo "\n--------------- git pull start ---------------\n"
                // git_secret_key是您的git在jenkins凭据管了的id
                git branch: "$branch", credentialsId: "${env.git_secret_key}", url: "${env.git_url}"
                echo "\n--------------- git pull end ---------------\n"
            }
        }
 
        stage("code build") {
            steps {
                echo "build path -Jenkinsfile defined 'buildDir' >>>  ${env.workspace_dir}"
                sh '''
ls -l /bin/sh
source /etc/profile
go version
go env -w GOPROXY=https://goproxy.io,direct
go env -w GOPATH=${workspace_dir}/bin
cd ${build_dir}
go mod tidy
rm -rf ./build/*
go build -o ./build/${app_name} main.go
cp -r ./conf ./build
                '''
                echo "\n--------------- build end ---------------\n"
            }
        }
 
        stage("deploy") {
            steps {
                script {
                    echo "\n--------------- deploy 开始部署 start ---------------\n"
                    echo "\n--------------- deploy 开始部署 start ---------------\n"
                    remote = [:]
                    remote.name = "${env.deploy_remote_server}"
                    remote.host = "${env.deploy_remote_server}"
                    remote.port = 22
                    remote.allowAnyHosts = true
					remote.encoding = 'UTF-8'
					remote.timeoutSec = 5
					remote.retryCount = 3
					remote.retryWaitSec = 5   
                    withCredentials([usernamePassword(credentialsId: "${env.deploy_remote_secret_key}", passwordVariable: 'password', usernameVariable: 'userName')]) {
					    remote.user = "${userName}"
					    remote.password = "${password}"
                    }
                    uploadText = """
#!/bin/bash
if [ ! -d "${env.app_upload_path}" ];then
    mkdir -p ${env.app_upload_path}
else
    rm -rf ${env.app_upload_path}/*
fi
"""
                    writeFile file: "deploy-${env.app_name}.sh", text: uploadText
                    sshPut remote: remote, from: "deploy-${env.app_name}.sh", into: "."
                    sshScript remote: remote, script: "deploy-${env.app_name}.sh"
                    echo "\n--------------- upload file start ---------------\n"
                    sshPut remote:remote, from: "${build_dir}/build", into: "${env.app_upload_path}"
                    echo "\n--------------- upload file success ---------------\n"

                    echo "\n--------------- deploy start ---------------\n"
                    startText = """#!/bin/bash
./deploy-stop-server.sh ${app_name}
sleep 2
./deploy-api.sh deploy ${app_name}  ${conf_env}
"""
                    writeFile file: "deploy-${env.app_name}.sh", text: startText
                    sshPut remote: remote, from: "deploy-${env.app_name}.sh", into: "."
                    sshScript remote: remote, script: "deploy-${env.app_name}.sh"
                    echo "\n--------------- deploy success end ---------------\n"
                } 
                // script end
            }
        }
    }
    
    post {
        always {
            echo "\n--------------- 通知开始... ---------------\n"
        }
        success {
            dingtalk (
                // 钉钉机器人id
                robot: "您的机器人id",
                type:"MARKDOWN",
                atAll: false,
                title: "发布成功:${env.app_name}",
                text: [
                    "### ${env.app_name} ",
                    "---",
                    "- 任务:${env.app_name}",
                    "- 状态:<font color=#00CD00>发布成功</font>",
                    "- 分支:<font color=#00CD00>${branch}</font>",
                    "- 持续时间:${currentBuild.durationString}".split("and counting")[0],
                ],
                // phoneNum是您的电话号码
                at: [
                    "您的电话号码"
                ]
            )
        }
        failure {
            dingtalk (
            	// 钉钉机器人id
                robot: "您的机器人id",
                type:"MARKDOWN",
                atAll: false,
                title: "发布失败:${env.app_name}",
                text: [
                    "### ${env.app_name} ",
                    "---",
                    "- 任务:${env.app_name}",
                    "- 状态:<font color=#00CD00>发布失败</font>",
                    "- 分支:<font color=#00CD00>${branch}</font>",
                    "- 持续时间:${currentBuild.durationString}".split("and counting")[0],
                ],
                // phoneNum是您的电话号码
                at: [
                    "您的电话号码"
                ]
            )
        }
        unstable {
            echo "该任被标记为不稳定任务...."
        }
        changed {
            echo "\n--------------- 通知结束... ---------------\n"
        }
    }
}

Shell脚本(主要是针对ubuntu),同类请自行修改目录

特别注意,要吧这个文件放在您的要部署的服务器上并赋予执行权限

文件名为:  deploy-api.sh

#!/bin/bash
export APP_NAME=$2
export APP_ENV=$3
export APP_ROOT="/home/ubuntu/api"
export APP_PATH"=$APP_ROOT/app/$APP_NAME"
export APP_FILE"=$APP_ROOT/app/$APP_NAME/$APP_NAME"
export APP_LOG_PATH="$APP_ROOT/logs"
export APP_LOG="$APP_LOG_PATH/$APP_NAME/$APP_NAME-$(date "+%Y%m%d-%H%M%S").log"
export BUILD_UPLOAD_PATH="$APP_ROOT/build/$APP_NAME/build"
export BACK_PATH="$APP_ROOT/bak/$APP_NAME"

RANDOM_PORT=0

#判断端口占用情况,没占用0,占用返回1
function isPortExist {
   TCP_PID=`netstat -an | grep ":$1 " | awk '$1 == "tcp" && $NF == "LISTEN" {print $0}' | wc -l`
   UDP_PID=`netstat -an | grep ":$1 " | awk '$1 == "udp" && $NF == "0.0.0.0:*" {print $0}' | wc -l`
   (( TOTAL_PID = TCP_PID + UDP_PID ))
   if [ $TOTAL_PID == 0 ]; then
       echo "0"
   else
       echo "1"
   fi
}

#指定区间随机数
function randomRange {
   shuf -i $1-$2 -n1
}

#得到随机端口
function findRandomPort {
   temp_port=0
   while [ $RANDOM_PORT == 0 ]; do
       temp_port=`randomRange $1 $2`
       if [ `isPortExist $temp_port` == 0 ] ; then
              RANDOM_PORT=$temp_port
       fi
   done
   echo "RANDOM_PORT=$RANDOM_PORT"
}

# 调用函数获取随机端口 这里指定了8000~8999区间,从中任取一个未占用端口号
findRandomPort 8000 8999;
echo "运行文件名称:$0, 操作类型:$1, 应用名称:$2, 运行端口:$RANDOM_PORT,  配置文件环境:$3"


echo "开始新部署 $APP_NAME 服务"
if [ ! -d "$APP_PATH" ];then
    echo "创建部署文件夹 => $APP_PATH"
    mkdir -p "$APP_PATH"
fi
if [ ! -d "$APP_LOG_PATH/$APP_NAME" ];then
    echo "创建日志目录 => $APP_LOG_PATH/$APP_NAME"
    mkdir -p "$APP_LOG_PATH/$APP_NAME"
    touch "$APP_LOG"
fi
if [ ! -d "$BACK_PATH" ];then
    echo "创建备份文件夹 => $BACK_PATH"
    mkdir -p "$BACK_PATH"
fi
if [ ! -f "$APP_PATH/$APP_NAME" ];then
    echo "应用文件夹为空时移动上传的文件到部署目录 => $APP_PATH"
    mv $BUILD_UPLOAD_PATH/* $APP_PATH
else
    echo "备份文件 => $APP_PATH"
    rm -rf $BACK_PATH/*
    mv $APP_PATH/* $BACK_PATH
    echo "备份完成"
    sleep 3
    if [ -d "$BUILD_UPLOAD_PATH" ];then
        echo "移动上传的文件到部署目录进行部署"
        mv $BUILD_UPLOAD_PATH/* $APP_PATH
    else
        echo "部署失败 -> 构建的文件夹不存在"
    fi
fi
if [ -f "$APP_FILE" ];then
    echo "文件执行权限 chmod +x $APP_FILE"
    chmod +x $APP_FILE
    chmod 777 $APP_PATH/$APP_NAME
fi

echo "开始启动 $APP_NAME服务"
if [ ! -f "$APP_LOG" ];then
    echo "创建日志文件 =>  $APP_LOG"
    mkdir -p $APP_LOG_PATH/$APP_NAME
    touch $APP_LOG
fi

if [ -f "$APP_PATH/$APP_NAME" ];then
    echo "启动 --conf=$APP_PATH --active=$APP_ENV --port=$RANDOM_PORT"
    echo "log-path -> $APP_LOG"
    `nohup $APP_FILE --conf=$APP_PATH --active=$APP_ENV --port=$RANDOM_PORT > $APP_LOG 2>&1 &`
else
    echo "部署文件不存在, 部署失败!"
    exit 0
fi

RUN_PID=`ps -ef | grep $RANDOM_PORT | grep -v grep | awk '{print $2}'`
if [ "$RUN_PID" != "" ];then
    echo "$APP_NAME 服务启动成功端口为: $RANDOM_PORT, 进程: $RUN_PID >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
    echo "服务 $APP_NAME  部署成功!部署成功删除上传文件夹 => $BUILD_UPLOAD_PATH"
    if [ -d "$BUILD_UPLOAD_PATH" ];then
        rm -rf $BUILD_UPLOAD_PATH
    fi
    exit 0
else
    echo "$APP_NAME 服务部署失败 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
    echo "log-error-path => $APP_LOG"
    sleep 2
    for line in `cat $APP_LOG`
    do
  	echo $line
    done
    exit 1
fi

停止服务脚本

#!/bin/bash
APP_NAME=$1
echo $APP_NAME
PIDS=`ps -ef | grep "$APP_NAME" | grep -v "$0" | grep -v "grep" | awk '{print $2}'`
echo "pids: $PIDS"
for id in $PIDS;do
        echo "id: $id"
        kill -9 $id
done
echo "已经停止 $APP_NAME  服务"
exit 0

如有不对欢迎大家批评指正

标签:Pipeline,remote,APP,echo,env,PATH,Go,Jenkins,app
From: https://blog.51cto.com/u_10476803/6534917

相关文章

  • Mongodb GeoJSON 地理数据处理 其实我也很厉害
    相信如果提起地理数据的处理,首先想起的数据库就是postgis,对大名鼎鼎的postgresql + 插件的方式来将POSTGRESQL变成纯纯的地理数据处理的数据库,这是人尽皆知和童叟无欺的功能。 那么世界上如果我不想使用POSTGRESQL的 postgis来处理我的地理数据以外的选择,那么NO.2的选择......
  • transformers库的使用【一】——pipeline的简单使用
    transformers库的使用使用pipelineAPI来快速使用一些预训练模型使用预训练模型最简单的方法就是使用pipeline(),transformers提供了一些任务:1、情感分析(Sentmentanalysis):分析文本是正面的还是负面的2、文本生成(inEnglish):提供一个语句,模型将生成这条语句的下一句3、命名实体识......
  • MONGODB 奇怪12问 switch over
    开头还是介绍一下群,如果感兴趣polardb,mongodb,mysql,postgresql ,redis等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。最近我们公司的REDISDBA和MONGODBDBA在SWITCHOVER, 我提出了一些问题关于MONGODB的问题,来让两个DBA能更快的融合对方的......
  • ERROR 1153 (08S01): Got a packet bigger than 'max_allowed_packet' bytes
    今天在批量伪造测试数据时,MySQL收到下面异常:ERROR1153(08S01):Gotapacketbiggerthan'max_allowed_packet'bytes。这是因为没有调整mysql的默认配置,默认最大只能处理16M的文件,而我要导入的伪造数据有50M的一个SQL。于是调整配置文件:/etc/my.cnf修改mysql的最大允许包大小......
  • 蔬菜识别系统Python+TensorFlow+Django+卷积神经网络算法
    一、介绍蔬菜识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Django框架,开发网页端操作平台,实现用户上传一张图片识别其名称。二、效果图片三、演示视频+代码视频+完整......
  • 鸟类识别系统Python+Django+TensorFlow+卷积神经网络算法【完整代码】
    一、介绍鸟类识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Django框架,开发网页端操作平台,实现用户上传一张图片识别其名称。数据集选自加州理工学院200种鸟类数据集二、......
  • 蔬菜识别系统Python+TensorFlow+Django+卷积神经网络算法
    一、介绍蔬菜识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Django框架,开发网页端操作平台,实现用户上传一张图片识别其名称。二、效果图片三、演示视频+代码视频+完整代码:http......
  • ubuntu安装mongodb
    1.下载mongodbhttps://www.mongodb.com/try/download/community下载ubuntu的tgz版本2.解压tgz解压安装包到工作目录3.修改.bashrcexportMONGODB_HOME=xxx/mongodbexportPATH=$PATH:$MONGODB_HOME/bin4.启动mongodbmongod--dbpath$MONGODB_HOME/data/db--logpath$M......
  • Codeforces 1835F - Good Graph
    goodproblem,badround。判断YES还是NO很trivial,就直接跑最大匹配看看是不是\(n\)即可。如果是NO,那么考虑Hall定理的证明过程构造即可。具体方法就是找到左部任意一非匹配点,在残量网络上BFS可以到达的点,那所有可以到达的左部点形成的集合就是符合要求的反例。因为你......
  • mongodb-安装过程
    1、下载地址https://www.mongodb.com/try/download/community2、安装过程关闭THP,提高性能#vim/etc/rc.localiftest-f/sys/kernel/mm/transparent_hugepage/enabled;thenechonever>/sys/kernel/mm/transparent_hugepage/enabledfiiftest-f/sys/kernel/mm/t......