398 lines
15 KiB
Groovy
398 lines
15 KiB
Groovy
pipeline {
|
||
agent any
|
||
|
||
tools {
|
||
maven 'mvn3.8.8'
|
||
jdk 'jdk21'
|
||
}
|
||
|
||
parameters {
|
||
choice(
|
||
name: 'ENV',
|
||
choices: ['prod'],
|
||
description: '部署环境'
|
||
)
|
||
gitParameter(
|
||
branchFilter: 'origin/(.*)',
|
||
defaultValue: 'master',
|
||
name: 'GIT_BRANCH',
|
||
type: 'PT_BRANCH_TAG',
|
||
selectedValue: 'DEFAULT',
|
||
sortMode: 'NONE',
|
||
description: '选择代码分支: ',
|
||
quickFilterEnabled: true,
|
||
tagFilter: '*',
|
||
listSize: "5"
|
||
)
|
||
}
|
||
|
||
environment {
|
||
APP_NAME = 'flymoon-agent'
|
||
GIT_REPO = 'http://172.24.16.20/root/fly_moon_agent.git'
|
||
GIT_CREDS = 'fly_gitlab_auth'
|
||
BUILD_DIR = "${WORKSPACE}/flymoon-agent-provider"
|
||
TARGET_JDK_HOME = "/data/jdk-21.0.7"
|
||
TARGET_HOST_A = "43.153.98.191"
|
||
TARGET_HOST_B = "49.51.41.243"
|
||
DEPLOY_DIR = "/data/webapps/flymoon_agent"
|
||
}
|
||
|
||
stages {
|
||
stage('代码检出') {
|
||
steps {
|
||
script {
|
||
echo "=========================================="
|
||
echo "Git 仓库: ${env.GIT_REPO}"
|
||
echo "分支: ${params.GIT_BRANCH}"
|
||
echo "=========================================="
|
||
|
||
git branch: "${params.GIT_BRANCH}",
|
||
credentialsId: "${env.GIT_CREDS}",
|
||
url: "${env.GIT_REPO}"
|
||
}
|
||
}
|
||
}
|
||
|
||
stage('Maven 构建') {
|
||
steps {
|
||
echo "=========================================="
|
||
echo "执行 Maven 打包..."
|
||
echo "构建目录: ${env.BUILD_DIR}"
|
||
echo "=========================================="
|
||
|
||
sh """
|
||
cd ${env.BUILD_DIR}/bin/
|
||
sh package.sh
|
||
"""
|
||
}
|
||
}
|
||
|
||
stage('上传构建产物A') {
|
||
steps {
|
||
echo "=========================================="
|
||
echo "上传到: ${env.TARGET_HOST_A}:${env.DEPLOY_DIR}"
|
||
echo "=========================================="
|
||
|
||
sh """
|
||
scp ${env.BUILD_DIR}/target/${env.APP_NAME}.jar \
|
||
${env.TARGET_HOST_A}:${env.DEPLOY_DIR}/${env.APP_NAME}-new.jar
|
||
|
||
scp ${env.BUILD_DIR}/bin/start.sh \
|
||
${env.TARGET_HOST_A}:${env.DEPLOY_DIR}/
|
||
|
||
scp ${env.BUILD_DIR}/bin/stop.sh \
|
||
${env.TARGET_HOST_A}:${env.DEPLOY_DIR}/
|
||
"""
|
||
}
|
||
}
|
||
|
||
stage('上传构建产物B') {
|
||
steps {
|
||
echo "=========================================="
|
||
echo "上传到: ${env.TARGET_HOST_B}:${env.DEPLOY_DIR}"
|
||
echo "=========================================="
|
||
|
||
sh """
|
||
scp ${env.BUILD_DIR}/target/${env.APP_NAME}.jar \
|
||
${env.TARGET_HOST_B}:${env.DEPLOY_DIR}/${env.APP_NAME}-new.jar
|
||
|
||
scp ${env.BUILD_DIR}/bin/start.sh \
|
||
${env.TARGET_HOST_B}:${env.DEPLOY_DIR}/
|
||
|
||
scp ${env.BUILD_DIR}/bin/stop.sh \
|
||
${env.TARGET_HOST_B}:${env.DEPLOY_DIR}/
|
||
"""
|
||
}
|
||
}
|
||
|
||
|
||
stage('备份与替换') {
|
||
steps {
|
||
echo "=========================================="
|
||
echo "备份旧版本并替换 JAR 包..."
|
||
echo "=========================================="
|
||
|
||
sh """
|
||
ssh ${env.TARGET_HOST_A} '
|
||
cd ${env.DEPLOY_DIR} &&
|
||
|
||
if [ -f ${env.APP_NAME}.jar ]; then
|
||
echo "[INFO] 备份: ${env.APP_NAME}.jar -> ${env.APP_NAME}-backup.jar"
|
||
cp ${env.APP_NAME}.jar ${env.APP_NAME}-backup.jar
|
||
fi &&
|
||
|
||
echo "[INFO] 替换: ${env.APP_NAME}-new.jar -> ${env.APP_NAME}.jar"
|
||
mv ${env.APP_NAME}-new.jar ${env.APP_NAME}.jar &&
|
||
|
||
echo "[INFO] 设置脚本执行权限"
|
||
chmod +x start.sh stop.sh &&
|
||
|
||
echo "[SUCCESS] ${env.TARGET_HOST_A} JAR 替换完成"
|
||
'
|
||
"""
|
||
|
||
sh """
|
||
ssh ${env.TARGET_HOST_B} '
|
||
cd ${env.DEPLOY_DIR} &&
|
||
|
||
if [ -f ${env.APP_NAME}.jar ]; then
|
||
echo "[INFO] 备份: ${env.APP_NAME}.jar -> ${env.APP_NAME}-backup.jar"
|
||
cp ${env.APP_NAME}.jar ${env.APP_NAME}-backup.jar
|
||
fi &&
|
||
|
||
echo "[INFO] 替换: ${env.APP_NAME}-new.jar -> ${env.APP_NAME}.jar"
|
||
mv ${env.APP_NAME}-new.jar ${env.APP_NAME}.jar &&
|
||
|
||
echo "[INFO] 设置脚本执行权限"
|
||
chmod +x start.sh stop.sh &&
|
||
|
||
echo "[SUCCESS] ${env.TARGET_HOST_B} JAR 替换完成"
|
||
'
|
||
"""
|
||
}
|
||
}
|
||
|
||
stage('停止旧服务A') {
|
||
steps {
|
||
echo "=========================================="
|
||
echo "停止旧版本服务A..."
|
||
echo "=========================================="
|
||
|
||
sh """
|
||
ssh ${env.TARGET_HOST_A} '
|
||
cd ${env.DEPLOY_DIR} &&
|
||
|
||
if [ -f stop.sh ]; then
|
||
sh stop.sh || true
|
||
echo "[INFO] 等待服务完全停止..."
|
||
sleep 3
|
||
else
|
||
echo "[WARN] 未找到 stop.sh,跳过停止步骤"
|
||
fi
|
||
'
|
||
"""
|
||
}
|
||
}
|
||
|
||
stage('启动新服务A') {
|
||
steps {
|
||
echo "=========================================="
|
||
echo "启动新版本服务..."
|
||
echo "环境: ${params.ENV}"
|
||
echo "JDK: ${env.TARGET_JDK_HOME}"
|
||
echo "=========================================="
|
||
|
||
sh """
|
||
ssh ${env.TARGET_HOST_A} '
|
||
cd ${env.DEPLOY_DIR} &&
|
||
|
||
echo "[INFO] 执行启动命令: sh start.sh ${params.ENV} ${env.TARGET_JDK_HOME}"
|
||
sh start.sh ${params.ENV} ${env.TARGET_JDK_HOME} &&
|
||
|
||
echo "[INFO] 等待启动完成..."
|
||
sleep 5 &&
|
||
|
||
if [ -f app.pid ]; then
|
||
PID=\$(cat app.pid)
|
||
if ps -p \$PID > /dev/null 2>&1; then
|
||
echo "[SUCCESS] 服务启动成功 (PID: \$PID)"
|
||
else
|
||
echo "[ERROR] 服务启动失败"
|
||
tail -50 /root/logs/${env.APP_NAME}/app.log
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "[ERROR] PID 文件不存在"
|
||
exit 1
|
||
fi
|
||
'
|
||
"""
|
||
}
|
||
}
|
||
|
||
stage('健康检查A') {
|
||
steps {
|
||
echo "=========================================="
|
||
echo "执行服务健康检查..."
|
||
echo "=========================================="
|
||
|
||
sh """
|
||
ssh ${env.TARGET_HOST_A} '
|
||
cd ${env.DEPLOY_DIR} &&
|
||
|
||
echo "[INFO] 等待服务完全启动..."
|
||
sleep 10 &&
|
||
|
||
if [ -f app.pid ]; then
|
||
PID=\$(cat app.pid)
|
||
|
||
if ps -p \$PID > /dev/null 2>&1; then
|
||
echo "[SUCCESS] 服务运行正常 (PID: \$PID)"
|
||
echo ""
|
||
|
||
# 显示进程信息
|
||
echo "==================== 进程信息 ===================="
|
||
ps -p \$PID -o pid,etime,cmd --no-headers
|
||
echo ""
|
||
|
||
# 显示日志位置
|
||
echo "==================== 日志位置 ===================="
|
||
echo "[INFO] 管道日志: /root/logs/${env.APP_NAME}/app.log"
|
||
echo "[INFO] 应用日志目录: ${env.DEPLOY_DIR}/logs"
|
||
echo "=================================================="
|
||
else
|
||
echo "[ERROR] 服务进程已退出"
|
||
echo "==================== 错误日志 ===================="
|
||
tail -100 /root/logs/${env.APP_NAME}/app.log
|
||
echo "=================================================="
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "[ERROR] PID 文件不存在"
|
||
exit 1
|
||
fi
|
||
'
|
||
"""
|
||
}
|
||
}
|
||
|
||
stage('停止旧服务B') {
|
||
steps {
|
||
echo "=========================================="
|
||
echo "停止旧版本服务B..."
|
||
echo "=========================================="
|
||
|
||
sh """
|
||
ssh ${env.TARGET_HOST_B} '
|
||
cd ${env.DEPLOY_DIR} &&
|
||
|
||
if [ -f stop.sh ]; then
|
||
sh stop.sh || true
|
||
echo "[INFO] 等待服务完全停止..."
|
||
sleep 3
|
||
else
|
||
echo "[WARN] 未找到 stop.sh,跳过停止步骤"
|
||
fi
|
||
'
|
||
"""
|
||
}
|
||
}
|
||
|
||
stage('启动新服务A') {
|
||
steps {
|
||
echo "=========================================="
|
||
echo "启动新版本服务..."
|
||
echo "环境: ${params.ENV}"
|
||
echo "JDK: ${env.TARGET_JDK_HOME}"
|
||
echo "=========================================="
|
||
|
||
sh """
|
||
ssh ${env.TARGET_HOST_B} '
|
||
cd ${env.DEPLOY_DIR} &&
|
||
|
||
echo "[INFO] 执行启动命令: sh start.sh ${params.ENV} ${env.TARGET_JDK_HOME}"
|
||
sh start.sh ${params.ENV} ${env.TARGET_JDK_HOME} &&
|
||
|
||
echo "[INFO] 等待启动完成..."
|
||
sleep 5 &&
|
||
|
||
if [ -f app.pid ]; then
|
||
PID=\$(cat app.pid)
|
||
if ps -p \$PID > /dev/null 2>&1; then
|
||
echo "[SUCCESS] 服务启动成功 (PID: \$PID)"
|
||
else
|
||
echo "[ERROR] 服务启动失败"
|
||
tail -50 /root/logs/${env.APP_NAME}/app.log
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "[ERROR] PID 文件不存在"
|
||
exit 1
|
||
fi
|
||
'
|
||
"""
|
||
}
|
||
}
|
||
|
||
stage('健康检查A') {
|
||
steps {
|
||
echo "=========================================="
|
||
echo "执行服务健康检查..."
|
||
echo "=========================================="
|
||
|
||
sh """
|
||
ssh ${env.TARGET_HOST_B} '
|
||
cd ${env.DEPLOY_DIR} &&
|
||
|
||
echo "[INFO] 等待服务完全启动..."
|
||
sleep 10 &&
|
||
|
||
if [ -f app.pid ]; then
|
||
PID=\$(cat app.pid)
|
||
|
||
if ps -p \$PID > /dev/null 2>&1; then
|
||
echo "[SUCCESS] 服务运行正常 (PID: \$PID)"
|
||
echo ""
|
||
|
||
# 显示进程信息
|
||
echo "==================== 进程信息 ===================="
|
||
ps -p \$PID -o pid,etime,cmd --no-headers
|
||
echo ""
|
||
|
||
# 显示日志位置
|
||
echo "==================== 日志位置 ===================="
|
||
echo "[INFO] 管道日志: /root/logs/${env.APP_NAME}/app.log"
|
||
echo "[INFO] 应用日志目录: ${env.DEPLOY_DIR}/logs"
|
||
echo "=================================================="
|
||
else
|
||
echo "[ERROR] 服务进程已退出"
|
||
echo "==================== 错误日志 ===================="
|
||
tail -100 /root/logs/${env.APP_NAME}/app.log
|
||
echo "=================================================="
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "[ERROR] PID 文件不存在"
|
||
exit 1
|
||
fi
|
||
'
|
||
"""
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
post {
|
||
success {
|
||
echo ""
|
||
echo "=================================================="
|
||
echo " 部署成功 "
|
||
echo "=================================================="
|
||
echo "环境: ${params.ENV}"
|
||
echo "部署路径: ${env.DEPLOY_DIR}"
|
||
echo "JDK 路径: ${env.TARGET_JDK_HOME}"
|
||
echo "Git 分支: ${params.GIT_BRANCH}"
|
||
echo "=================================================="
|
||
}
|
||
|
||
failure {
|
||
echo ""
|
||
echo "=================================================="
|
||
echo " 部署失败 "
|
||
echo "=================================================="
|
||
echo "请检查上述日志排查问题"
|
||
echo "常见问题:"
|
||
echo "1. 检查目标服务器 JDK 路径是否正确"
|
||
echo "2. 检查 SSH 连接是否正常"
|
||
echo "3. 查看应用启动日志"
|
||
echo "=================================================="
|
||
}
|
||
|
||
always {
|
||
echo ""
|
||
echo "流水线状态: ${currentBuild.currentResult}"
|
||
echo "执行耗时: ${currentBuild.durationString}"
|
||
}
|
||
}
|
||
}
|