news 2026/2/4 18:04:18

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/1/29 13:57:20

LobeChat能否用于编写Prometheus告警规则?可观测性增强

LobeChat 能否用于编写 Prometheus 告警规则?可观测性增强 在现代云原生系统中,服务的稳定性早已不再依赖“看日志猜问题”的经验主义。随着微服务和 Kubernetes 的普及,系统的复杂度呈指数级上升,传统监控方式已难以应对快速定位…

作者头像 李华
网站建设 2026/2/4 4:14:11

大模型学习全攻略:七阶段系统学习路线图,从基础到实战应用,非常详细收藏我这一篇就够了

文章提供了七阶段大模型学习路线图:从数学和编程基础开始,经历机器学习、深度学习、自然语言处理等阶段,到大规模语言模型及其应用,最后是持续学习与进阶。每个阶段都推荐了相关书籍、论文和在线课程作为学习资源,并附…

作者头像 李华
网站建设 2026/1/27 21:26:51

YOLOv5中使用torch加载自定义模型进行目标检测

YOLOv5中使用torch加载自定义模型进行目标检测 在智能安防、工业质检和机器人视觉等实际场景中,我们常常面临这样一个问题:训练好的YOLOv5模型如何快速部署到真实环境中?很多开发者卡在“训练完成却不会用”的尴尬阶段——明明.pt文件就躺在r…

作者头像 李华
网站建设 2026/2/3 10:31:45

LobeChat能否隐藏源码信息?增强系统隐蔽性

LobeChat 能否隐藏源码信息?从架构设计看系统隐蔽性实现 在企业纷纷将大语言模型(LLM)引入业务流程的今天,一个看似简单的问题却常被忽视:当你部署了一个 AI 对话界面时,有没有人能轻易“扒开”你的技术底裤…

作者头像 李华
网站建设 2026/2/3 12:14:36

React 的桶算法详解

桶算法(Bucket Algorithm)是React调度系统的核心秘密武器!它通过巧妙的时间分组,实现了批量更新和优先级管理。让我深入解释这个精妙的设计。内容结合了deepseek产出,旨在碎片化理解一些react 的概念,以便后…

作者头像 李华