首页/系统与基础设施/自动化运维速查/批量执行的幂等回滚设计
批量执行与作业50 条

批量执行的幂等回滚设计

幂等回滚要求回退动作可以重复执行且结果一致:先判断当前状态,只在确实需要时才动作,第二次执行不产生新变化。批量场景必须这样设计,因为回滚常在故障中执行,很可能中途失败后重跑;不幂等的回滚会把已经退好的节点又改坏一次。

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌‌​‌‌​​​‌​​‌‌​​​​‌​‌‌‌​‌​​​‌‌​​​‌‌​‌‌​‌​​​​​‌​‌‌​‌​‌‌​​‌​‌​‌‌‌‌​​​​‌‌​​‌​‌​‌‌​​​‌‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌​​‌​‌‌​​‌​​​‌‌​​‌​‌​‌‌​‌‌​‌​‌‌‌​​​​​‌‌​‌‌‌‌​‌‌‌​‌​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​​‌​‌‌​‌​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌​‌‌​​​‌‌​‌‌​​​‌‌​​​‌​​‌‌​​​​‌​‌‌​​​‌‌​‌‌​‌​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

幂等回滚要满足什么

回滚有两个容易踩空的前提:一是回滚动作本身要幂等,先查现场状态再决定动不动作,重复执行不改变结果;二是要承认有些变更不可回退——数据写入、结构变更、证书吊销大多只能前滚(用修复往前推进),不能靠回退解决。批量回滚还应保持逆序与分批:后改的先退,避免依赖被提前撤掉;分批回退则避免所有节点同时回到旧版本后容量骤降。回滚方案要在变更前演练,不能等故障时才第一次执行。

基本信息

回滚对象配置回滚、版本回滚、数据变更(多数不可逆,需前滚方案)
幂等做法先查当前状态,仅在偏离目标时动作,动作可重复执行
执行顺序逆序回退,后改的先退;分批回退,避免容量骤降
关键约束回滚须有超时与人工兜底,事先演练而非临时编写

典型使用场景

  • 分批发布失败:回退已发布批次,同时冻结后续批次
  • 配置批量下发失败:一部分主机已生效,另一部分未生效
  • 灰度验证不通过:只回退灰度批次,全量尚未开始
  • 数据库结构变更:确认不可回退后改用前滚修复方案
  • 缓存与索引重建失败:保留旧版本继续服务,清理半成品
  • 回滚中途失败:可安全重跑,不用先判断上次退到哪一步

幂等且逆序的回滚

幂等且逆序的回滚
# 单机回滚:先查当前指向,已在目标版本就跳过,保证可重复执行
rollback_one() {
  host="$1"
  cur=$(ssh -n "$host" 'readlink -f /opt/app/current' || true)
  if [ "$cur" = "/opt/app/releases/v1.4.0" ]; then
    echo "$host 已是目标版本,跳过"
    return 0
  fi
  ssh -n "$host" 'ln -sfn /opt/app/releases/v1.4.0 /opt/app/current && systemctl reload app'
}

# 逆序回滚:后改的先退,避免依赖被提前撤掉
for h in $(tac changed-hosts.txt); do
  timeout 60 bash -c "rollback_one $h" \
    || echo "$(date -u +%FT%TZ) $h 回滚失败,需人工处理" >> rollback-err.log
done

# 回滚完成后回读校验:确认版本、进程与端口状态都回到基线

变更类型与回滚手段

变更类型可否回退回滚手段主要风险
配置文件可以还原上一版本并重载未重载导致看似回滚实则未生效
应用版本可以切回旧版本目录并重启新旧版本依赖不兼容
数据写入通常不可前滚修复或用备份恢复到时间点回退可能丢数据
结构变更多数不可前滚补丁或反向结构脚本中间态无法服务
证书与密钥受限恢复旧证书需注意吊销状态已吊销证书不能再用
回滚与前滚的选择标准是「哪种方式更快恢复服务」。当前滚补丁几分钟能修好、回滚要走数据恢复且丢数据时,前滚通常更合适;决策应在变更前就写进方案,而不是在故障中临场讨论。
回滚过程中会出现新旧并存的中间态:一半节点已退、一半未退,接口兼容与数据格式可能都不成立。评估回滚方案时要把这段窗口的风险单独算一遍。

易错点

  • 回滚脚本自身不幂等:重跑一次把已经退好的节点又改成新状态,越滚越乱
  • 只回滚配置不回滚数据或依赖:配置退了、数据格式还是新的,服务仍然起不来
  • 回滚不分批一次全退:所有节点同时回到旧版本,容量与性能瞬间不足
  • 回滚没有超时与上限:单个节点卡住,整批回滚流程悬停无人推进
  • 回滚方案从不演练:第一次真正执行就发生在故障中,边写边试错过恢复窗口

数据来源与参考

  • Ansible 官方文档:模块幂等性与 block/rescue 失败处理
  • Kubernetes 官方文档:kubectl rollout undo 与版本历史
  • Google SRE 工作手册:发布与回滚实践

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/automation/batch-execution-idempotent-rollback.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌‌​‌‌​​​‌​​‌‌​​​​‌​‌‌‌​‌​​​‌‌​​​‌‌​‌‌​‌​​​​​‌​‌‌​‌​‌‌​​‌​‌​‌‌‌‌​​​​‌‌​​‌​‌​‌‌​​​‌‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌​​‌​‌‌​​‌​​​‌‌​​‌​‌​‌‌​‌‌​‌​‌‌‌​​​​​‌‌​‌‌‌‌​‌‌‌​‌​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​​‌​‌‌​‌​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌​‌‌​​​‌‌​‌‌​​​‌‌​​​‌​​‌‌​​​​‌​‌‌​​​‌‌​‌‌​‌​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​