本文目录导读:

我来详细介绍几种Shell脚本实现批量回滚策略的方法。
基础版本:文件版本管理回滚
#!/bin/bash
# 配置
BACKUP_DIR="/backup/app"
APP_DIR="/opt/myapp"
BACKUP_PREFIX="app_backup"
# 显示可用的备份列表
list_backups() {
echo "可用的备份版本:"
ls -1t $BACKUP_DIR/${BACKUP_PREFIX}_*.tar.gz 2>/dev/null | awk -F'_' '{print $NF}' | sed 's/\.tar\.gz//'
}
# 回滚到指定版本
rollback_to_version() {
local version=$1
local backup_file="${BACKUP_DIR}/${BACKUP_PREFIX}_${version}.tar.gz"
if [ ! -f "$backup_file" ]; then
echo "错误:备份文件不存在: $backup_file"
return 1
fi
echo "开始回滚到版本: $version"
# 停止应用
systemctl stop myapp 2>/dev/null || killall myapp 2>/dev/null
# 备份当前版本(可选)
if [ "$2" != "--no-backup" ]; then
tar -czf "${BACKUP_DIR}/pre_rollback_$(date +%Y%m%d_%H%M%S).tar.gz" $APP_DIR 2>/dev/null
fi
# 恢复指定版本
rm -rf $APP_DIR/*
tar -xzf "$backup_file" -C $APP_DIR
# 设置权限
chmod -R 755 $APP_DIR
# 启动应用
systemctl start myapp 2>/dev/null || nohup $APP_DIR/bin/start.sh &
echo "回滚完成"
}
# 批量回滚(多个服务)
batch_rollback() {
local services=("$@")
local version=${services[0]}
unset services[0]
for service in "${services[@]}"; do
echo "正在处理服务: $service"
# 设置不同的应用目录
local app_dir="/opt/$service"
local backup_file="${BACKUP_DIR}/${service}_${version}.tar.gz"
if [ -f "$backup_file" ]; then
tar -xzf "$backup_file" -C $app_dir
echo "服务 $service 回滚完成"
else
echo "警告:服务 $service 的备份文件不存在"
fi
done
}
# 主函数
case "$1" in
list)
list_backups
;;
rollback)
if [ -z "$2" ]; then
echo "请指定版本号"
exit 1
fi
rollback_to_version "$2" "$3"
;;
batch)
shift
batch_rollback "$@"
;;
*)
echo "用法: $0 {list|rollback <version> [--no-backup]|batch <version> <service1> [service2...]}"
;;
esac
进阶版本:带状态检查和回滚策略
#!/bin/bash
# 配置文件
CONFIG_FILE="/etc/rollback.conf"
LOG_FILE="/var/log/rollback.log"
# 初始化日志
init_log() {
exec 1>>$LOG_FILE 2>&1
echo "=== $(date '+%Y-%m-%d %H:%M:%S') 开始回滚操作 ==="
}
# 读取配置文件
load_config() {
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
else
echo "配置文件 $CONFIG_FILE 不存在,使用默认配置"
# 默认配置
ROLLBACK_TIMEOUT=300
MAX_RETRIES=3
HEALTH_CHECK_URL="http://localhost:8080/health"
fi
}
# 健康检查函数
health_check() {
local url=${1:-$HEALTH_CHECK_URL}
local timeout=${2:-30}
for i in $(seq 1 $timeout); do
if curl -s -f "$url" > /dev/null 2>&1; then
echo "健康检查通过"
return 0
fi
echo "等待服务启动... ($i/$timeout)"
sleep 1
done
echo "健康检查失败"
return 1
}
# 回滚前检查
pre_rollback_check() {
local service=$1
local app_dir=$2
# 检查目录是否存在
if [ ! -d "$app_dir" ]; then
echo "错误:应用目录 $app_dir 不存在"
return 1
fi
# 检查备份文件
local backup_file="${BACKUP_DIR}/${service}_latest.tar.gz"
if [ ! -f "$backup_file" ]; then
echo "错误:备份文件 $backup_file 不存在"
return 1
fi
return 0
}
# 执行回滚
execute_rollback() {
local service=$1
local version=$2
local retry_count=0
while [ $retry_count -lt $MAX_RETRIES ]; do
echo "第 $((retry_count + 1)) 次尝试回滚 $service 到版本 $version"
# 停止服务
systemctl stop $service 2>/dev/null
sleep 2
# 恢复备份
local backup_file="${BACKUP_DIR}/${service}_${version}.tar.gz"
local app_dir=$(get_app_dir $service)
# 备份当前版本
tar -czf "${BACKUP_DIR}/${service}_current_backup.tar.gz" -C $app_dir . 2>/dev/null
# 执行回滚
rm -rf $app_dir/*
tar -xzf "$backup_file" -C $app_dir
# 启动服务
systemctl start $service 2>/dev/null
# 等待并检查健康状态
sleep 5
if health_check; then
echo "服务 $service 回滚成功"
return 0
fi
# 如果回滚失败,自动恢复
echo "回滚失败,正在恢复..."
tar -xzf "${BACKUP_DIR}/${service}_current_backup.tar.gz" -C $app_dir
systemctl restart $service
sleep 5
((retry_count++))
done
echo "服务 $service 回滚失败,已超过最大重试次数"
return 1
}
# 批量回滚策略
batch_rollback_strategy() {
local strategy=$1
shift
local services=("$@")
local version=$1
case $strategy in
"sequential")
# 顺序回滚
for service in "${services[@]}"; do
if ! execute_rollback "$service" "$version"; then
echo "顺序回滚在 $service 失败,停止后续回滚"
return 1
fi
done
;;
"parallel")
# 并行回滚
for service in "${services[@]}"; do
execute_rollback "$service" "$version" &
done
wait
;;
"canary")
# 金丝雀发布策略(先部分回滚)
if [ ${#services[@]} -ge 2 ]; then
# 先回滚一个实例验证
echo "金丝雀回滚:先回滚 ${services[0]}"
if execute_rollback "${services[0]}" "$version"; then
echo "金丝雀验证通过,继续回滚其他服务"
for ((i=1; i<${#services[@]}; i++)); do
execute_rollback "${services[$i]}" "$version"
done
else
echo "金丝雀回滚失败,停止回滚"
return 1
fi
fi
;;
"rolling")
# 滚动回滚(逐个回滚,保持服务可用)
local success_count=0
local total=${#services[@]}
for service in "${services[@]}"; do
echo "滚动回滚:[$((success_count+1))/$total] $service"
if execute_rollback "$service" "$version"; then
((success_count++))
else
echo "滚动回滚在 $service 失败"
# 可以选择继续或停止
# return 1
fi
done
echo "滚动回滚完成:$success_count/$total 成功"
;;
*)
echo "不支持的策略: $strategy"
echo "支持: sequential, parallel, canary, rolling"
return 1
;;
esac
}
# 获取应用目录(根据服务名)
get_app_dir() {
local service=$1
# 可以根据实际配置调整
if [[ $service == *"app"* ]]; then
echo "/opt/$service"
else
echo "/opt/$service"
fi
}
# 主函数
main() {
init_log
load_config
local command=$1
shift
case $command in
"rollback")
# 用法: rollback <version> <service> [--force]
local version=$1
local service=$2
local force=$3
if [ "$force" == "--force" ]; then
echo "强制执行回滚..."
fi
if pre_rollback_check "$service" "$(get_app_dir $service)" || [ "$force" == "--force" ]; then
execute_rollback "$service" "$version"
else
echo "回滚前检查失败"
exit 1
fi
;;
"batch")
# 用法: batch <strategy> <version> <service1> [service2...]
local strategy=$1
local version=$2
shift 2
batch_rollback_strategy "$strategy" "$version" "$@"
;;
*)
echo "用法: $0 {rollback|batch}"
echo " rollback <version> <service> [--force]"
echo " batch <strategy> <version> <service1> [service2...]"
echo ""
echo "策略说明:"
echo " sequential - 顺序回滚"
echo " parallel - 并行回滚"
echo " canary - 金丝雀回滚"
echo " rolling - 滚动回滚"
;;
esac
}
# 执行主函数
main "$@"
Git版本回滚方案
#!/bin/bash
# Git仓库批量回滚
git_batch_rollback() {
local repos=("$1") # 仓库列表
local target_commit=$2
local branch=${3:-"master"}
for repo in "${repos[@]}"; do
echo "处理仓库: $repo"
cd "$repo" || {
echo "无法进入目录: $repo"
continue
}
# 保存当前状态
current_branch=$(git rev-parse --abbrev-ref HEAD)
# 创建回滚分支
rollback_branch="rollback/$(date +%Y%m%d_%H%M%S)"
git branch "$rollback_branch"
# 执行回滚
git checkout "$branch"
git pull origin "$branch"
git reset --hard "$target_commit"
# 强制推送(小心使用)
git push origin "$branch" --force
if [ $? -eq 0 ]; then
echo "仓库 $repo 回滚到 $target_commit 成功"
else
echo "仓库 $repo 回滚失败"
# 回滚到之前的状态
git checkout "$current_branch"
fi
done
}
# 使用示例
# git_batch_rollback "/var/www/project1 /var/www/project2" "abc123def" "main"
Docker容器回滚
#!/bin/bash
# Docker容器批量回滚
docker_batch_rollback() {
local services=($1)
local image_tag=$2
local registry=${3:-"registry.example.com"}
for service in "${services[@]}"; do
echo "回滚服务: $service"
# 获取当前版本
current_version=$(docker inspect --format '{{.Config.Image}}' $service 2>/dev/null)
# 拉取旧版本镜像
docker pull "${registry}/${service}:${image_tag}"
# 停止并移除容器
docker stop "$service" 2>/dev/null
docker rm "$service" 2>/dev/null
# 启动旧版本
docker run -d \
--name "$service" \
--restart always \
"${registry}/${service}:${image_tag}"
# 检查运行状态
sleep 3
if docker ps --filter "name=$service" --filter "status=running" | grep -q "$service"; then
echo "服务 $service 回滚成功"
else
echo "服务 $service 回滚失败,检查日志..."
docker logs "$service" --tail 20
fi
done
}
# Kubernetes版本回滚
k8s_rollback() {
local deployments=($1)
local revision=$2
for deploy in "${deployments[@]}"; do
echo "回滚 deployment: $deploy"
# 查看可用版本
kubectl rollout history deployment "$deploy"
# 执行回滚
if [ -n "$revision" ]; then
kubectl rollout undo deployment "$deploy" --to-revision="$revision"
else
kubectl rollout undo deployment "$deploy"
fi
# 等待回滚完成
kubectl rollout status deployment "$deploy" --timeout=300s
if [ $? -eq 0 ]; then
echo "Deployment $deploy 回滚成功"
else
echo "Deployment $deploy 回滚失败"
fi
done
}
完整的批量回滚管理器
#!/bin/bash
# 配置文件
ROLLBACK_CONFIG="rollback.conf"
SERVICE_LIST="services.txt"
# 创建示例配置文件
create_config() {
cat > "$ROLLBACK_CONFIG" << 'EOF'
# 回滚配置
BACKUP_DIR="/backup"
ROLLBACK_TIMEOUT=300
HEALTH_CHECK_INTERVAL=5
MAX_RETRY=3
NOTIFY_EMAIL="admin@example.com"
EOF
cat > "$SERVICE_LIST" << 'EOF'
# 服务名 应用目录 启动命令 健康检查URL
myapp /opt/myapp "systemctl start myapp" http://localhost:8080/health
api-gateway /opt/gateway "systemctl start gateway" http://localhost:9090/health
auth-service /opt/auth "systemctl start auth" http://localhost:8081/health
EOF
}
# 批量回滚管理器
rollback_manager() {
local action=$1
local version=$2
# 加载服务列表
while IFS=' ' read -r service_name app_dir start_cmd health_url; do
# 跳过注释和空行
[[ $service_name =~ ^#.*$ || -z $service_name ]] && continue
echo "========================"
echo "处理服务: $service_name"
echo "目录: $app_dir"
echo "========================="
case $action in
"rollback")
# 执行回滚
backup_file="${BACKUP_DIR}/${service_name}_${version}.tar.gz"
if [ ! -f "$backup_file" ]; then
echo "备份文件不存在: $backup_file"
send_notification "$service_name" "失败" "备份文件不存在"
continue
fi
# 停止服务
eval "$start_cmd stop" 2>/dev/null
# 备份当前版本
tar -czf "${BACKUP_DIR}/${service_name}_pre_rollback.tar.gz" -C "$app_dir" . 2>/dev/null
# 恢复指定版本
rm -rf "$app_dir"/*
tar -xzf "$backup_file" -C "$app_dir"
# 启动服务
eval "$start_cmd start" 2>/dev/null
# 健康检查
sleep $HEALTH_CHECK_INTERVAL
if curl -s -f "$health_url" > /dev/null 2>&1; then
echo "服务 $service_name 回滚成功"
send_notification "$service_name" "成功" "已回滚到版本 $version"
else
echo "服务 $service_name 健康检查失败,执行回滚恢复"
# 恢复之前的版本
tar -xzf "${BACKUP_DIR}/${service_name}_pre_rollback.tar.gz" -C "$app_dir"
eval "$start_cmd restart"
send_notification "$service_name" "失败" "健康检查失败,已自动恢复"
fi
;;
"list")
echo "可用备份:"
ls -1 ${BACKUP_DIR}/${service_name}_*.tar.gz 2>/dev/null | awk -F'/' '{print $NF}'
;;
esac
done < "$SERVICE_LIST"
}
# 发送通知
send_notification() {
local service=$1
local status=$2
local message=$3
echo "[NOTIFICATION] Service: $service, Status: $status, Message: $message"
# 实际可以添加邮件、钉钉等通知
# mail -s "Rollback Report" "$NOTIFY_EMAIL" <<< "$message"
}
# 主程序
main() {
# 检查配置
if [ ! -f "$ROLLBACK_CONFIG" ]; then
echo "配置文件不存在,创建默认配置..."
create_config
fi
source "$ROLLBACK_CONFIG"
# 检查参数
if [ $# -lt 1 ]; then
echo "用法: $0 {create-config|list|rollback <version>}"
echo " create-config - 创建示例配置文件"
echo " list - 列出所有备份"
echo " rollback - 执行批量回滚"
exit 1
fi
case $1 in
"create-config")
create_config
echo "配置文件已创建: $ROLLBACK_CONFIG, $SERVICE_LIST"
;;
"list")
rollback_manager "list"
;;
"rollback")
if [ -z "$2" ]; then
echo "请指定回滚版本"
exit 1
fi
rollback_manager "rollback" "$2"
;;
*)
echo "未知命令: $1"
exit 1
;;
esac
}
# 执行
main "$@"
使用示例
# 1. 创建配置 ./rollback.sh create-config # 2. 列出可用备份 ./rollback.sh list # 3. 批量回滚到指定版本 ./rollback.sh rollback "20231201_120000" # 4. 高级用法:使用不同策略 ./rollback_manager.sh batch rolling "v1.2.1" service1 service2 service3 ./rollback_manager.sh batch canary "v1.2.1" service1 service2 service3
这些脚本提供了从简单到复杂的批量回滚策略,可以根据实际需求选择合适的版本,记住在生产环境中使用前一定要充分测试!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播