幂等重跑设计
幂等重跑的目标是让「再跑一次」既安全又有意义:只补未完成的部分,已完成的目标跳过。实现方式包括执行前检查目标的当前状态以决定是否动作、把已完成目标记录到状态文件、按内容指纹或版本判断是否需要变更、以及使用支持差异判定的声明式工具。核心风险在于状态记录与真实环境不一致:记录说完成了但环境已被手工改动,跳过就会漏做;记录失效又会导致重复执行。
基本信息
| 核心机制 | 状态文件记录已完成目标、执行前状态检查、内容指纹或版本比对 |
|---|---|
| 常用手段 | 仅对失败集合重跑、检查模式(只报告不执行)、重跑清单文件 |
| 主要风险 | 状态记录与真实环境不一致,导致漏做或重复做 |
| 关键要求 | 判定条件能表达「当前是否已符合目标状态」 |
典型使用场景
- 批量执行中途失败,只需要补上失败的部分
- 日常执行需要重复运行但不希望产生副作用
- 先用检查模式评估影响,再决定是否真正执行
- 配置收敛任务每次运行都需要判断差异
- 发布或升级失败后需要安全地重新执行
重跑与跳过写法
重跑与跳过写法
awk -F'\t' '$3!=0{print $1}' last-run.tsv > retry.txt # 取出非零退出码的主机
ansible-playbook deploy.yml --limit @retry.txt # 只对失败集合重跑
# 执行前检查目标状态,已符合预期则跳过
if ssh -n "$h" 'systemctl is-active --quiet app'; then
printf '%s\talready-ok\n' "$h" >> done.txt
else
ssh -n "$h" 'systemctl start app' && printf '%s\tok\n' "$h" >> done.txt
fi
ansible-playbook deploy.yml --check --diff # 先看差异,不落地改动重跑机制与失效原因
| 机制 | 作用 | 失效原因 |
|---|---|---|
| 状态文件跳过 | 已完成目标直接跳过 | 记录被删除,或环境已被重建 |
| 状态检查 | 按当前实际状态决定动作 | 判定条件写得过粗 |
| 内容指纹比对 | 仅在内容变化时传输或更新 | 指纹文件丢失或过期 |
| 版本或标签比对 | 只处理未达标的实例 | 版本号未随内容变化而更新 |
| 检查模式 | 评估影响而不落地改动 | 检查结果与实际执行存在细微差异 |
真正可靠的幂等来自目标状态判定,而进度记录只是加速手段。任何跳过决定都应能用当前环境状态解释,否则环境被手工改动之后重跑会漏做,而且漏做通常不产生任何报错。
状态记录与真实环境不一致时,重跑可能触发本该跳过的重启或变更。重跑高风险操作之前,先核对少量样本的当前状态,再决定是否信任历史记录。