news 2026/4/30 23:24:09

Jenkins备份及回滚方式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Jenkins备份及回滚方式

PS:备份脚本存放位置(使用时将脚本放置环境服务包下)注意权限问题

在使用前备份脚本和回滚脚本需要根据实际的服务名称进行修改,并创建备份目录

使用SSH Pubishers执行脚本

执行脚本后,备份文件存放位置(以服务名称为文件,服务加时间戳为文件版本)

根据构建时间给予备份文件

回滚jar

备份脚本

#!/bin/bash set -e # 出错立即退出,避免静默失败 # ========== 备份配置项(根据实际修改) ========== APP_NAME="admin" # 应用名称 ONLINE_APP_DIR="/home/work/app/service/xxx/" # 线上应用包目录 BACKUP_DIR="/home/work/app/backup/xxx/" # 备份目录 RETENTION_DAYS=0 # 备份保留天数 AUDIT_LOG="/home/work/soft/logs/backup_audit.log" # 备份审计日志 # ========== 核心逻辑 ========== # 1. 生成精确到秒的时间戳 TIMESTAMP=$(date +%Y%m%d%H%M%S) # 2. 定义文件路径 ONLINE_APP_PATH="${ONLINE_APP_DIR}/${APP_NAME}.jar" BACKUP_APP_PATH="${BACKUP_DIR}/${APP_NAME}-${TIMESTAMP}.jar" # 3. 校验线上包是否存在 if [ ! -f "${ONLINE_APP_PATH}" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: 线上包 ${ONLINE_APP_PATH} 不存在,备份失败!" >> ${AUDIT_LOG} echo "ERROR: 线上包不存在,备份失败!" exit 1 fi # 4. 执行备份(-p 保留文件属性:权限、时间、属主) echo "[$(date +'%Y-%m-%d %H:%M:%S')] INFO: 开始备份 ${ONLINE_APP_PATH} -> ${BACKUP_APP_PATH}" >> ${AUDIT_LOG} cp -p ${ONLINE_APP_PATH} ${BACKUP_APP_PATH} # 5. 校验备份是否成功(对比文件大小) ONLINE_SIZE=$(du -b ${ONLINE_APP_PATH} | awk '{print $1}') BACKUP_SIZE=$(du -b ${BACKUP_APP_PATH} | awk '{print $1}') if [ "${ONLINE_SIZE}" != "${BACKUP_SIZE}" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: 备份包大小不一致,备份失败!" >> ${AUDIT_LOG} rm -f ${BACKUP_APP_PATH} # 删除损坏的备份包 exit 1 fi # 6. 清理过期备份 echo "[$(date +'%Y-%m-%d %H:%M:%S')] INFO: 清理${RETENTION_DAYS}天前的备份..." >> ${AUDIT_LOG} find ${BACKUP_DIR} -name "${APP_NAME}-*.jar" -mtime +${RETENTION_DAYS} -delete >> ${AUDIT_LOG} 2>&1 # 7. 记录审计日志 echo "[$(date +'%Y-%m-%d %H:%M:%S')] SUCCESS: 备份成功,备份包路径:${BACKUP_APP_PATH}" >> ${AUDIT_LOG} # 8. 输出成功信息(供Jenkins日志查看) echo "备份成功!" echo "备份包路径:${BACKUP_APP_PATH}" echo "当前备份列表(按时间倒序):" ls -lh ${BACKUP_DIR}/${APP_NAME}-*.jar | sort -k9r exit 0

回滚脚本

#!/bin/bash set -e # 出错立即退出,避免静默失败 # ========== 备份配置项(根据实际修改) ========== APP_NAME="admin" # 应用名称 ONLINE_APP_DIR="/home/work/app/service/xxx/" # 线上应用包目录 BACKUP_DIR="/home/work/app/backup/xxx/" # 备份目录 RETENTION_DAYS=0 # 备份保留天数 AUDIT_LOG="/home/work/soft/logs/backup_audit.log" # 备份审计日志 # ========== 核心逻辑 ========== # 1. 生成精确到秒的时间戳 TIMESTAMP=$(date +%Y%m%d%H%M%S) # 2. 定义文件路径 ONLINE_APP_PATH="${ONLINE_APP_DIR}/${APP_NAME}.jar" BACKUP_APP_PATH="${BACKUP_DIR}/${APP_NAME}-${TIMESTAMP}.jar" # 3. 校验线上包是否存在 if [ ! -f "${ONLINE_APP_PATH}" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: 线上包 ${ONLINE_APP_PATH} 不存在,备份失败!" >> ${AUDIT_LOG} echo "ERROR: 线上包不存在,备份失败!" exit 1 fi # 4. 执行备份(-p 保留文件属性:权限、时间、属主) echo "[$(date +'%Y-%m-%d %H:%M:%S')] INFO: 开始备份 ${ONLINE_APP_PATH} -> ${BACKUP_APP_PATH}" >> ${AUDIT_LOG} cp -p ${ONLINE_APP_PATH} ${BACKUP_APP_PATH} # 5. 校验备份是否成功(对比文件大小) ONLINE_SIZE=$(du -b ${ONLINE_APP_PATH} | awk '{print $1}') BACKUP_SIZE=$(du -b ${BACKUP_APP_PATH} | awk '{print $1}') if [ "${ONLINE_SIZE}" != "${BACKUP_SIZE}" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: 备份包大小不一致,备份失败!" >> ${AUDIT_LOG} rm -f ${BACKUP_APP_PATH} # 删除损坏的备份包 exit 1 fi # 6. 清理过期备份 echo "[$(date +'%Y-%m-%d %H:%M:%S')] INFO: 清理${RETENTION_DAYS}天前的备份..." >> ${AUDIT_LOG} find ${BACKUP_DIR} -name "${APP_NAME}-*.jar" -mtime +${RETENTION_DAYS} -delete >> ${AUDIT_LOG} 2>&1 # 7. 记录审计日志 echo "[$(date +'%Y-%m-%d %H:%M:%S')] SUCCESS: 备份成功,备份包路径:${BACKUP_APP_PATH}" >> ${AUDIT_LOG} # 8. 输出成功信息(供Jenkins日志查看) echo "备份成功!" echo "备份包路径:${BACKUP_APP_PATH}" echo "当前备份列表(按时间倒序):" ls -lh ${BACKUP_DIR}/${APP_NAME}-*.jar | sort -k9r exit 0 [root@rocky9-0 scripts]# cat rollback_service.sh #!/bin/bash set -e # 出错立即退出,避免静默失败 # ========== 回滚配置项(和备份脚本完全对齐) ========== APP_NAME="XXX" # 应用名称 ONLINE_APP_DIR="/home/lyszwork/app/service/XXX/" # 线上应用包目录 BACKUP_DIR="/home/lyszwork/app/backup/XXX" # 备份目录 AUDIT_LOG="/home/lyszwork/soft/logs/rollback_service.log" # 复用备份审计日志 # 【核心配置】应用启停命令( STOP_APP_CMD="sh /home/lyszwork/app/service/common-service-center/deploy.sh stop" START_APP_CMD="sh /home/lyszwork/app/service/common-service-center/deploy.sh start" # ========== 核心回滚逻辑 ========== # 1. 前置校验:检查备份目录是否存在 if [ ! -d "${BACKUP_DIR}" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: 备份目录 ${BACKUP_DIR} 不存在!" >> ${AUDIT_LOG} echo "ERROR: 备份目录不存在,无法回滚!" exit 1 fi # 2. 列出所有备份包(按时间倒序),筛选上一个版本 # 获取备份包列表(排除当前行),按时间戳降序排列 BACKUP_LIST=($(ls ${BACKUP_DIR}/${APP_NAME}-*.jar 2>/dev/null | sort -r)) if [ ${#BACKUP_LIST[@]} -eq 0 ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: 未找到任何备份包!" >> ${AUDIT_LOG} echo "ERROR: 无备份包可回滚!" exit 1 fi # 选择“上一个版本”(列表第一个即为最新备份,也就是要回滚的目标版本) TARGET_BACKUP=${BACKUP_LIST[0]} echo "[$(date +'%Y-%m-%d %H:%M:%S')] INFO: 选定回滚版本:${TARGET_BACKUP}" >> ${AUDIT_LOG} echo "✅ 选定回滚版本:${TARGET_BACKUP}" # 3. 备份当前线上包(防止回滚失败) CURRENT_TIMESTAMP=$(date +%Y%m%d%H%M%S) BACKUP_BEFORE_ROLLBACK="${BACKUP_DIR}/${APP_NAME}-current-before-rollback-${CURRENT_TIMESTAMP}.jar" echo "[$(date +'%Y-%m-%d %H:%M:%S')] INFO: 备份当前线上包到 ${BACKUP_BEFORE_ROLLBACK}" >> ${AUDIT_LOG} cp -p ${ONLINE_APP_DIR}/${APP_NAME}.jar ${BACKUP_BEFORE_ROLLBACK} 2>/dev/null || { echo "[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: 当前线上包不存在,直接使用备份包覆盖!" >> ${AUDIT_LOG} } # 4. 停止应用(避免Jar包被占用) echo "[$(date +'%Y-%m-%d %H:%M:%S')] INFO: 停止应用 ${APP_NAME}..." >> ${AUDIT_LOG} echo "🔴 停止应用中..." ${STOP_APP_CMD} || { echo "[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: 应用停止命令执行失败(可能应用已停止)" >> ${AUDIT_LOG} echo "⚠️ 应用停止命令执行失败(可能应用已停止),继续回滚..." } # 5. 执行回滚:替换线上Jar包 echo "[$(date +'%Y-%m-%d %H:%M:%S')] INFO: 开始回滚,替换线上包..." >> ${AUDIT_LOG} echo "🔄 执行回滚替换Jar包..." cp -p ${TARGET_BACKUP} ${ONLINE_APP_DIR}/${APP_NAME}.jar # 校验回滚是否成功(对比文件大小) BACKUP_SIZE=$(du -b ${TARGET_BACKUP} | awk '{print $1}') ROLLBACK_SIZE=$(du -b ${ONLINE_APP_DIR}/${APP_NAME}.jar | awk '{print $1}') if [ "${BACKUP_SIZE}" != "${ROLLBACK_SIZE}" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: 回滚包大小不一致,回滚失败!" >> ${AUDIT_LOG} # 回滚失败:恢复之前备份的当前包 cp -p ${BACKUP_BEFORE_ROLLBACK} ${ONLINE_APP_DIR}/${APP_NAME}.jar 2>/dev/null rm -f ${BACKUP_BEFORE_ROLLBACK} echo "❌ 回滚失败,已恢复原线上包!" exit 1 fi # 6. 启动应用 echo "[$(date +'%Y-%m-%d %H:%M:%S')] INFO: 启动应用 ${APP_NAME}..." >> ${AUDIT_LOG} echo "🟢 启动应用中..." ${START_APP_CMD} || { echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: 应用启动失败!" >> ${AUDIT_LOG} echo "❌ 应用启动失败,请手动检查!" exit 1 } # 7. 记录成功日志 echo "[$(date +'%Y-%m-%d %H:%M:%S')] SUCCESS: 回滚完成!目标版本:${TARGET_BACKUP}" >> ${AUDIT_LOG} echo -e "\n✅ 回滚成功!" echo "📌 回滚版本:${TARGET_BACKUP}" echo "📌 线上包路径:${ONLINE_APP_DIR}/${APP_NAME}.jar" echo "📌 请检查应用日志,确认服务正常运行!" exit 0
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 8:00:50

AI不会淘汰产品经理,但不会AI的会!大模型学习指南(建议收藏)

文章强调AI时代已全面到来,产品经理必须拥抱AI避免被淘汰。作者建议向取得实际成果的人学习AI知识,而非纯理论。特别推荐参加人人都是产品经理大会,邀请了腾讯音乐、金山办公、字节跳动等有AI落地经验的产品经理分享实战经验。我不想给你们罗…

作者头像 李华
网站建设 2026/5/1 4:44:01

智能双卡设计:SIM卡硬件架构与软件配置核心解析!

智能双卡设计的核心在于硬件架构的合理性与软件配置的适配性。本文首先剖析硬件层面的双卡卡槽布局、电源域划分及信号隔离设计要点,再深入解析软件配置中的驱动适配、卡状态机管理与运营商优先级设置逻辑,通过软硬件协同视角,为开发者提供智…

作者头像 李华
网站建设 2026/5/1 4:46:09

无需API限制!使用LobeChat调用自有模型节省token成本

无需API限制!使用LobeChat调用自有模型节省token成本 在AI应用日益普及的今天,越来越多企业与开发者开始面临一个现实问题:明明只是想做个智能问答助手,为什么每次对话都要花几毛钱?当你的客服系统每天处理上千次请求…

作者头像 李华
网站建设 2026/5/1 4:45:44

Linly-Talker:构建可交互的数字人对话系统

Linly-Talker:构建可交互的数字人对话系统 在智能客服逐渐取代机械应答、虚拟主播开始挑战真人出镜的时代,我们正站在一场人机交互范式的转折点上。过去需要影视级制作流程才能实现的“会说话的数字面孔”,如今只需一张照片和一段语音&#…

作者头像 李华
网站建设 2026/5/1 5:45:05

分享150V耐压 输出电流可达3A的浮地架构DC-DC芯片

一、概述OC5810是一款支持宽电压输入的开关降压型DC-DC,内置 150V/100mΩ 功率MOS,最高输入电压150V。 OC5810具有低待机功耗、高效率、低纹波、优异的母线电压调整率和负载调整率等特性。 支持大电流输出,输出电流可达 3A 以上。 OC5810同时…

作者头像 李华
网站建设 2026/5/1 6:50:49

kotaemon本地化数据处理与隐私保护方案

Kotaemon 本地化数据处理与隐私保护方案 在企业越来越依赖人工智能进行内部决策、客户服务和知识管理的今天,一个尖锐的问题摆在面前:我们能否既享受大模型带来的智能便利,又不让敏感信息暴露在第三方云端?尤其是在金融、医疗、法…

作者头像 李华