FunctionGraph 事件重复投递的幂等设计:原子占位 + 内容指纹

举报
yd_285894438 发表于 2026/10/24 18:04:13 2026/10/24
【摘要】 函数工作流(FunctionGraph)触发器在对象存储事件通知场景下是至少一次投递。网络重试、事件重复上报都会让同一个对象事件被处理多次,表现为重复写库、重复发消息。

背景

函数工作流(FunctionGraph)触发器在对象存储事件通知场景下是至少一次投递。网络重试、事件重复上报都会让同一个对象事件被处理多次,表现为重复写库、重复发消息。

为什么不能只靠去重表

最直接的做法是处理前查一次数据库,但高并发下查询与写入之间存在竞态,两个实例可能同时判定未处理。去重表必须依赖唯一键约束或原子写,否则挡不住并发。

幂等键设计

用 bucket + object key + ETag 组合成幂等键。ETag 随对象内容变化,同一个键重复事件指向同一份内容,天然适合做去重标识。把幂等键哈希后作为主键写入,重复写入会失败,从而只放行一次。

原子占位实现

以 Redis(DCS)为例:SET idem:{hash} 1 NX EX 86400,返回 OK 说明抢到执行权,返回 nil 说明已处理过,直接返回成功。TTL 覆盖业务最长重试窗口,避免键无限增长。没有 Redis 时可以用 OBS 的条件写:PutObject 到 .done/{hash} 并带 If-None-Match: *,冲突即已存在。

处理顺序

第一步校验事件字段完整;第二步计算幂等键并原子占位;第三步执行业务;第四步写完成标记。业务失败时释放占位键,让重试可以继续,避免死锁式阻塞。

验证方法

用同一份事件连续调用三次函数,观察业务表只有一条记录、消息只发出一条;再用并发工具同时打十个请求,确认只有一个成功占位。最后检查 TTL 过期后旧事件重放能被正确处理。

小结

至少一次投递无法在触发器侧关掉,只能在消费侧做幂等。幂等键要包含内容标识,占位要原子,失败要能释放,这三点做到,重复消费就不再是问题。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。