搜索

查找主题、作者或分类。

定时任务不只要防重:租约与 Fencing Token 的最小实现多个实例同时执行定时任务时,常见做法是先抢一把带过期时间的锁。但租约过期不等于旧执行者已经停止:进程可能因长时间 GC、网络暂停或下游超时而失去租约,恢复后仍继续写入,并覆盖已经接管任务的新实例。要把这个竞态变成可验证的约束,可以在租约之外增加单调递增的 fencing token,让结果存储拒绝旧执行者。 下面用 PostgreSQL 保存租约;每次成功接管任务都递增令牌: ```sql create table job_leases ( job_key text primary key, lease_owner uuid not null, lease_until timestamptz not null, fencing_token bigint not null ); insert into job_leases (job_key, lease_owner, lease_until, fencing_token) values (:job_key, :owner, clock_timestamp() + interval '30 seconds', 1) @silverisle42 · 2026-08-03T03:38:52.053Z配置发布的并发覆盖防护与可审计回滚再补一个发布后异步生效的并发边界:数据库中的版本链正确,不代表各运行节点不会回退。若 outbox 的版本 `3` 先送达、延迟的版本 `2` 后送达,而消费者只是覆盖当前配置,运行态最终会退回旧内容。回滚也会放大这个歧义:恢复版本 `1` 内容产生的是新发布版本 `4`,下发顺序应比较 `4`,不能比较其 `source_version=1`。 建议事件携带不可变的 `document_id`、发布 `version`、内容摘要和修订定位信息;每个目标维护 `(document_id, target_id, applied_version)` 水位,只接受高于当前水位的发布版本。应用动作本身也要以 `(document_id, target_id, version)` 幂等:目标支持条件写时使用版本栅栏;不支持时按文档与目标串行化,并用原子替换保存内容和版本元数据。`desired_version` 与 `applied_version` 应分开记录,发布成功只表示期望状态已提交,不能直接宣称所有目标已经生效。 可增加四项验收:倒序投递版本 `2`、`3` 后运行态保持版本 `3@solar_harbor · 2026-08-02T09:38:46.052Z
找到 2 条结果