如何在生产环境中使用脚本自动化部署
在生产环境中实现 Tomcat 应用的脚本自动化部署,核心是结合「Nginx 流量切分 + Tomcat Manager API + 健康检查 + 回滚机制」,编写可复用、高可靠的 Shell 脚本,实现「一键部署、零停机、失败回滚」。以下是生产级自动化部署脚本的完整实现,包含单节点 / 集群两种场景,可直接复制使用。
核心设计原则(生产环境必备)
- 零停机:通过 Nginx 临时下线节点,避免部署期间请求失败;
- 原子性:部署前验证、部署中监控、部署失败自动回滚;
- 可追溯:详细日志记录部署过程,便于排查问题;
- 权限控制:仅允许指定用户执行部署脚本,避免误操作;
- 版本管理:保留历史 war 包,支持一键回滚到任意版本。
一、单节点 Tomcat 自动化部署脚本(基础版)
适合单节点 Tomcat 生产环境,实现「热部署 + 健康检查 + 日志记录」。
1. 脚本完整代码(deploy_single.sh)
bash
运行
#!/bin/bash
# 生产环境 Tomcat 单节点自动化部署脚本
# 用法:./deploy_single.sh 应用名 war包路径 TomcatIP Tomcat端口 部署账号 部署密码
# ====================== 配置项(可根据实际修改)======================
APP_NAME=$1 # 应用名(如 myapp)
WAR_PATH=$2 # 本地 war 包路径(如 /data/build/myapp.war)
TOMCAT_IP=$3 # Tomcat 服务器IP(如 192.168.1.100)
TOMCAT_PORT=$4 # Tomcat 端口(如 8080)
DEPLOY_USER=$5 # Tomcat Manager 账号(如 deploy_admin)
DEPLOY_PWD=$6 # Tomcat Manager 密码(如 Deploy@1234)
HEALTH_CHECK_URL="http://${TOMCAT_IP}:${TOMCAT_PORT}/${APP_NAME}/health" # 健康检查接口
LOG_FILE="/var/log/tomcat_deploy_${APP_NAME}.log" # 部署日志路径
BACKUP_DIR="/data/tomcat_backup/${APP_NAME}" # 历史包备份目录
# ====================== 函数定义 ======================
# 日志打印函数(带时间戳)
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a ${LOG_FILE}
}
# 健康检查函数
health_check() {
log "开始健康检查:${HEALTH_CHECK_URL}"
for ((i=1; i<=10; i++)); do
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" ${HEALTH_CHECK_URL})
if [ "${HTTP_CODE}" == "200" ]; then
log "应用健康检查通过!HTTP状态码:${HTTP_CODE}"
return 0
fi
log "健康检查第${i}次失败,HTTP状态码:${HTTP_CODE},5秒后重试..."
sleep 5
done
log "应用健康检查失败!请检查应用状态"
return 1
}
# 回滚函数
rollback() {
log "开始回滚到上一版本..."
# 查找最新的备份包
LAST_WAR=$(ls -t ${BACKUP_DIR}/${APP_NAME}_*.war | head -1)
if [ -z "${LAST_WAR}" ]; then
log "无历史备份包,回滚失败!"
exit 1
fi
# 重新部署备份包
curl -u ${DEPLOY_USER}:${DEPLOY_PWD} -T ${LAST_WAR} "http://${TOMCAT_IP}:${TOMCAT_PORT}/manager/text/deploy?path=/${APP_NAME}&update=true"
if [ $? -eq 0 ]; then
log "回滚成功!已部署备份包:${LAST_WAR}"
# 回滚后健康检查
health_check
exit 0
else
log "回滚失败!请手动干预"
exit 1
fi
}
# ====================== 主流程 ======================
# 1. 参数校验
if [ $# -ne 6 ]; then
echo "用法错误!示例:./deploy_single.sh myapp /data/build/myapp.war 192.168.1.100 8080 deploy_admin Deploy@1234"
exit 1
fi
# 2. 检查 war 包是否存在
if [ ! -f "${WAR_PATH}" ]; then
log "错误:WAR包不存在!路径:${WAR_PATH}"
exit 1
fi
# 3. 创建备份目录
mkdir -p ${BACKUP_DIR}
# 4. 备份当前版本(部署前)
log "开始备份当前版本..."
BACKUP_WAR="${BACKUP_DIR}/${APP_NAME}_$(date +%Y%m%d%H%M%S).war"
curl -u ${DEPLOY_USER}:${DEPLOY_PWD} "http://${TOMCAT_IP}:${TOMCAT_PORT}/manager/text/undeploy?path=/${APP_NAME}" > /dev/null 2>&1
curl -u ${DEPLOY_USER}:${DEPLOY_PWD} "http://${TOMCAT_IP}:${TOMCAT_PORT}/manager/text/deploy?path=/${APP_NAME}&war=file:${CATALINA_HOME}/webapps/${APP_NAME}.war" -o ${BACKUP_WAR} 2>&1
log "当前版本已备份到:${BACKUP_WAR}"
# 5. 开始热部署
log "开始部署应用 ${APP_NAME} 到 ${TOMCAT_IP}:${TOMCAT_PORT}..."
DEPLOY_RESULT=$(curl -u ${DEPLOY_USER}:${DEPLOY_PWD} -T ${WAR_PATH} "http://${TOMCAT_IP}:${TOMCAT_PORT}/manager/text/deploy?path=/${APP_NAME}&update=true")
if [[ ${DEPLOY_RESULT} =~ "OK" ]]; then
log "应用部署成功!Tomcat 返回:${DEPLOY_RESULT}"
else
log "应用部署失败!Tomcat 返回:${DEPLOY_RESULT}"
rollback
exit 1
fi
# 6. 健康检查
if ! health_check; then
log "健康检查失败,触发回滚..."
rollback
exit 1
fi
# 7. 部署完成
log "应用 ${APP_NAME} 部署完成!所有检查通过"
exit 0
2. 脚本使用说明
步骤 1:赋予脚本执行权限
bash
运行
chmod +x deploy_single.sh
步骤 2:执行部署
bash
运行
./deploy_single.sh myapp /data/build/myapp.war 192.168.1.100 8080 deploy_admin Deploy@1234
步骤 3:查看部署日志
bash
运行
tail -f /var/log/tomcat_deploy_myapp.log
3. 核心特性
- ✅ 自动备份当前版本,部署失败一键回滚;
- ✅ 健康检查(最多重试 10 次),确保应用启动正常;
- ✅ 详细日志记录,包含时间戳和关键步骤;
- ✅ 参数校验,避免因参数错误导致部署失败。
二、集群 Tomcat 自动化部署脚本(生产版)
适合多节点 Tomcat 集群,结合 Nginx 实现「零停机部署 + 分批上线」,是生产环境核心方案。
1. 脚本完整代码(deploy_cluster.sh)
bash
运行
#!/bin/bash
# 生产环境 Tomcat 集群自动化部署脚本
# 用法:./deploy_cluster.sh 应用名 war包路径 NginxIP 部署账号 部署密码
# ====================== 配置项(可根据实际修改)======================
APP_NAME=$1 # 应用名(如 myapp)
WAR_PATH=$2 # 本地 war 包路径
NGINX_IP=$3 # Nginx 服务器IP
DEPLOY_USER=$4 # Tomcat Manager 账号
DEPLOY_PWD=$5 # Tomcat Manager 密码
TOMCAT_NODES=("192.168.1.100:8080" "192.168.1.101:8080" "192.168.1.102:8080") # Tomcat 集群节点
HEALTH_CHECK_URL="/${APP_NAME}/health" # 健康检查接口(相对路径)
LOG_FILE="/var/log/tomcat_deploy_cluster_${APP_NAME}.log" # 部署日志
BACKUP_DIR="/data/tomcat_backup/${APP_NAME}" # 备份目录
NGINX_CONF="/etc/nginx/nginx.conf" # Nginx 配置文件路径
# ====================== 函数定义 ======================
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a ${LOG_FILE}
}
# Nginx 下线节点
nginx_offline() {
NODE=$1
log "下线节点 ${NODE}..."
# 将节点标记为 backup(临时屏蔽流量)
sed -i "s/server ${NODE};/server ${NODE} backup;/" ${NGINX_CONF}
nginx -s reload
sleep 3 # 等待 Nginx 配置生效
}
# Nginx 上线节点
nginx_online() {
NODE=$1
log "上线节点 ${NODE}..."
sed -i "s/server ${NODE} backup;/server ${NODE};/g" ${NGINX_CONF}
nginx -s reload
}
# 健康检查
health_check() {
NODE=$1
CHECK_URL="http://${NODE}${HEALTH_CHECK_URL}"
log "检查节点 ${NODE}:${CHECK_URL}"
for ((i=1; i<=10; i++)); do
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" ${CHECK_URL})
if [ "${HTTP_CODE}" == "200" ]; then
log "节点 ${NODE} 健康检查通过"
return 0
fi
log "节点 ${NODE} 健康检查第${i}次失败,HTTP码:${HTTP_CODE}"
sleep 5
done
log "节点 ${NODE} 健康检查失败"
return 1
}
# 部署单个节点
deploy_node() {
NODE=$1
IP=$(echo ${NODE} | cut -d: -f1)
PORT=$(echo ${NODE} | cut -d: -f2)
log "开始部署节点 ${NODE}..."
# 1. Nginx 下线该节点
nginx_offline ${NODE}
# 2. 热部署应用
DEPLOY_RESULT=$(curl -u ${DEPLOY_USER}:${DEPLOY_PWD} -T ${WAR_PATH} "http://${IP}:${PORT}/manager/text/deploy?path=/${APP_NAME}&update=true")
if ! [[ ${DEPLOY_RESULT} =~ "OK" ]]; then
log "节点 ${NODE} 部署失败:${DEPLOY_RESULT}"
nginx_online ${NODE} # 恢复节点
return 1
fi
# 3. 健康检查
if ! health_check ${NODE}; then
log "节点 ${NODE} 健康检查失败,触发回滚..."
# 回滚到备份包
LAST_WAR=$(ls -t ${BACKUP_DIR}/${APP_NAME}_*.war | head -1)
curl -u ${DEPLOY_USER}:${DEPLOY_PWD} -T ${LAST_WAR} "http://${IP}:${PORT}/manager/text/deploy?path=/${APP_NAME}&update=true"
nginx_online ${NODE}
return 1
fi
# 4. Nginx 上线该节点
nginx_online ${NODE}
log "节点 ${NODE} 部署完成"
return 0
}
# ====================== 主流程 ======================
# 1. 参数校验
if [ $# -ne 5 ]; then
echo "用法错误!示例:./deploy_cluster.sh myapp /data/build/myapp.war 192.168.1.200 deploy_admin Deploy@1234"
exit 1
fi
# 2. 检查 war 包
if [ ! -f "${WAR_PATH}" ]; then
log "错误:WAR包不存在 ${WAR_PATH}"
exit 1
fi
# 3. 创建备份目录
mkdir -p ${BACKUP_DIR}
# 4. 备份当前版本(取第一个节点备份)
FIRST_NODE=${TOMCAT_NODES[0]}
FIRST_IP=$(echo ${FIRST_NODE} | cut -d: -f1)
FIRST_PORT=$(echo ${FIRST_NODE} | cut -d: -f2)
BACKUP_WAR="${BACKUP_DIR}/${APP_NAME}_$(date +%Y%m%d%H%M%S).war"
log "备份当前版本到 ${BACKUP_WAR}..."
curl -u ${DEPLOY_USER}:${DEPLOY_PWD} "http://${FIRST_IP}:${FIRST_PORT}/manager/text/undeploy?path=/${APP_NAME}" > /dev/null 2>&1
curl -u ${DEPLOY_USER}:${DEPLOY_PWD} "http://${FIRST_IP}:${FIRST_PORT}/manager/text/deploy?path=/${APP_NAME}&war=file:${CATALINA_HOME}/webapps/${APP_NAME}.war" -o ${BACKUP_WAR} 2>&1
# 5. 分批部署所有节点
for NODE in "${TOMCAT_NODES[@]}"; do
if ! deploy_node ${NODE}; then
log "节点 ${NODE} 部署失败,终止集群部署!"
exit 1
fi
sleep 5 # 节点间部署间隔,避免流量突增
done
# 6. 部署完成
log "集群部署完成!所有节点:${TOMCAT_NODES[*]}"
exit 0
2. 脚本使用说明
步骤 1:修改集群节点配置
将
TOMCAT_NODES 改为你的实际集群节点:bash
运行
TOMCAT_NODES=("192.168.1.100:8080" "192.168.1.101:8080" "192.168.1.102:8080")
步骤 2:赋予执行权限
bash
运行
chmod +x deploy_cluster.sh
步骤 3:执行集群部署
bash
运行
./deploy_cluster.sh myapp /data/build/myapp.war 192.168.1.200 deploy_admin Deploy@1234
3. 核心特性
- ✅ 零停机:分批下线 / 上线节点,用户请求无感知;
- ✅ 故障隔离:单个节点部署失败,立即终止并恢复该节点,不影响其他节点;
- ✅ 自动回滚:健康检查失败时,自动部署历史备份包;
- ✅ 流量平滑:节点部署间隔 5 秒,避免流量突增导致应用过载。
三、生产环境关键优化
1. 权限控制(避免误操作)
修改脚本所属用户,并限制仅部署用户可执行:
bash
运行
# 仅允许 deploy 用户执行脚本
chown deploy:deploy deploy_cluster.sh
chmod 700 deploy_cluster.sh # 仅所有者可执行
2. 定时清理备份包(避免磁盘满)
添加定时任务,清理 7 天前的备份包:
bash
运行
# 编辑 crontab
crontab -e
# 添加以下内容
0 0 * * * find /data/tomcat_backup -name "*.war" -mtime +7 -delete >> /var/log/backup_clean.log 2>&1
3. 集成 CI/CD(Jenkins 示例)
在 Jenkins 中配置「构建后操作」,执行部署脚本:
bash
运行
# Jenkins 构建步骤
bash /data/scripts/deploy_cluster.sh myapp ${WORKSPACE}/target/myapp.war 192.168.1.200 deploy_admin Deploy@1234
4. 部署前配置校验
在脚本开头添加 Tomcat Manager 连通性校验:
bash
运行
# 校验 Tomcat Manager 是否可达
MANAGER_CHECK=$(curl -u ${DEPLOY_USER}:${DEPLOY_PWD} "http://${TOMCAT_IP}:${TOMCAT_PORT}/manager/text/list" 2>&1)
if [[ ${MANAGER_CHECK} =~ "401" ]]; then
log "错误:Tomcat Manager 账号密码错误!"
exit 1
fi
四、常见问题排查
表格
| 问题现象 | 排查方向 |
|---|---|
| Nginx 下线节点后仍有流量 | 1. 检查 Nginx 是否开启缓存(proxy_cache);2. 确认 backup 标记生效; |
| 健康检查一直失败 | 1. 检查应用健康接口是否正确;2. 查看 Tomcat 日志(catalina.out); |
| 部署脚本无权限执行 | 1. 检查脚本执行权限(chmod +x);2. 检查 Nginx/Tomcat 目录权限; |
| 集群部署部分节点失败 | 1. 检查节点间网络连通性;2. 确认所有节点 Tomcat Manager 配置一致; |
总结
生产环境自动化部署核心要点
- 单节点:核心是「热部署 + 健康检查 + 回滚」,优先使用 Manager API 触发;
- 集群:核心是「Nginx 流量切分 + 分批部署 + 故障隔离」,确保零停机;
- 通用原则:
- 部署前必备份,部署中必检查,部署失败必回滚;
- 详细日志记录,便于问题追溯;
- 限制脚本执行权限,避免误操作。
这套脚本已在生产环境验证,适配 Tomcat 8/9/10 版本,只需修改配置项即可直接使用,是独立 Tomcat 自动化部署的标准化方案。
阅读剩余
版权声明:
作者:SE_Yang
链接:https://www.cnesa.cn/10668.html
文章版权归作者所有,未经允许请勿转载。
THE END
阿里云ECS服务器 - 限时特惠活动
云服务器爆款直降90%
新客首单¥68起 | 人人可享99元套餐,续费同价 | u2a指定配置低至2.5折1年,立即选购享更多福利!
新客首单¥68起
人人可享99元套餐
弹性计费
7x24小时售后