外观
Lease、Heartbeat、重试和幂等如何配合?
标准回答
EachOf 的处理任务先持久化,再由 Worker 领取。Lease 表示 Worker 在一段时间内拥有处理权,Heartbeat 用来续期;如果 Worker 宕机或长时间没有续期,任务可以在租约过期后被重新分配。
这解决的是“任务不要永久卡在一个失联 Worker 上”,但不代表任务只会执行一次。例如 A 卡住后租约过期,B 接手执行,随后 A 又恢复,此时两个执行过程可能同时存在。因此还需要幂等控制重复效果,并在提交环节防止过期处理结果覆盖有效状态。幂等键也要对应具体业务操作和版本,不能把合法的新版本误判成重复。
失败处理上,临时错误适合有界重试;反复失败的任务进入 Dead Letter,保留原因,便于修复后受控重放。无限重试会浪费模型调用和计算资源,还可能让真正需要人工处理的问题长期被掩盖。
所以我对这套机制的描述是:允许故障条件下重复执行,通过持久化、租约回收、幂等和提交约束控制结果。它不是仅靠一个任务表就实现跨系统的 exactly-once。
关键机制
- 领取、续期和完成都需要校验任务身份与当前归属;仅靠心跳不能消除所有并发执行。
- 过期 Worker 的写入需要提交代次、领取凭证或其他条件校验来防护;材料未注明具体方案,不能直接声称已有 fencing token。
- 重试区分临时错误与不可恢复错误,设置次数与退避;Dead Letter 需要观察、修复和可控重放。
通俗例子
Worker A 卡住,Lease 过期后 B 接手,随后 A 又恢复。幂等与提交归属检查要防止 A、B 对同一任务产生互相覆盖或重复效果。
追问与回答
这能实现 exactly-once 吗?
我不会作这个承诺。网络超时后,调用方可能不知道下游是否已经执行成功;租约过期后,旧 Worker 也可能恢复。更现实的目标是允许重试和重复执行,但同一个业务操作的重复结果不会产生额外效果。如果还涉及外部系统,它也需要提供幂等接口或结果核对能力。仅靠我本地记录“已完成”,不能证明外部副作用恰好发生一次。
Heartbeat 成功就说明任务正常吗?
不一定。续期线程还在运行,不代表业务处理有进展,例如模型调用长期挂起,Worker 仍可能继续发心跳。因此健康判断还要区分租约是否存活、任务是否超时、业务进度是否推进。Heartbeat 主要解决执行权回收,执行时限和卡住检测是另一层机制,不能用“有心跳”代替任务完成质量。
易混淆点
幂等键必须对应业务操作与版本;如果来源已经变化,不能把合法新版本误判成旧任务重复。
参考资料
内容来源
- Android 技术札记 · 原条目
eachof-worker