作业先后控制的实现
先后控制不必都上编排平台,轻量场景有更简单的方式:串行脚本调用、信号文件、状态位、消息触发、容器初始化步骤。关键要求有两条:等待必须带超时,条件不成立时要明确失败而不是无限循环;判断条件要看内容而不是只看文件是否存在,否则读到上一次执行留下的残留标记,下游就会在错误的前提下开始工作。跨主机的顺序控制还需要一个可信观察点,通常把状态写入集中存储。
基本信息
| 常见实现 | 串行脚本、信号文件(含内容校验)、数据库状态位、消息触发、容器初始化步骤 |
|---|---|
| 必须具备 | 等待超时、条件幂等、残留清理 |
| 跨主机场景 | 状态写入集中存储,不能只判断本地文件 |
| 失败行为 | 上游失败时下游应明确失败,而不是继续执行 |
典型使用场景
- 脚本 A 必须先完成,脚本 B 才能启动
- 数据库迁移完成之后才允许应用启动
- 等待上游产出文件出现后再开始处理
- 多台主机需要按顺序重启,例如先在备机验证
- 容器启动前需要等待依赖服务真正可用
带超时的先后控制
带超时的先后控制
deadline=$(( $(date +%s) + 300 )) # 等待上限 5 分钟
until [ -s /data/export/done.flag ]; do
[ "$(date +%s)" -gt "$deadline" ] && { echo "等待超时"; exit 1; }
sleep 5
done
grep -q "batch=$(date +%F)" /data/export/done.flag || { echo "标记不匹配,疑似残留"; exit 1; }
systemctl restart app && until curl -sf http://127.0.0.1:8080/healthz; do sleep 2; done # 就绪后再下一步实现方式对比
| 实现方式 | 适用场景 | 主要风险 |
|---|---|---|
| 串行脚本 | 单机简单流程 | 任一步失败后续不再执行,重试需自行设计 |
| 信号文件 | 脚本之间的松散协作 | 残留文件导致误判就绪 |
| 数据库状态位 | 跨主机与需要审计的流程 | 并发写冲突与状态清理不及时 |
| 消息触发 | 跨系统解耦 | 需处理重复投递与消息丢失 |
| 容器初始化步骤 | 容器内依赖启动顺序 | 只保证启动顺序,不保证依赖真的可用 |
等待条件要判断内容而不只是存在性:文件存在但内容来自上一次执行,这类误判在生产上常表现为随机的数据异常,排查时因为现象不稳定而非常耗时。
所有等待循环都必须有超时。依赖永久不可用时,没有超时的等待会让任务永久挂住,比直接失败更糟:它悄悄占用资源且不产生告警。