尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

企业微信二次开发:如何利用clientMsgId做好消息幂等

企业微信二次开发:如何利用clientMsgId做好消息幂等 昨晚快零点的时候一个做社群发售的大客户群直接炸锅了“你们这机器人是不是疯了客户群里问了一句优惠券怎么领机器人一口气连发了 5 遍一样的回复瞬间把群刷屏了好几个大R客户嫌烦直接退群了这损失算谁的”我赶紧连上他们的服务器看日志果不其然完全没做消息去重。一遇到网络抖动底层网关触发重试这帮兄弟的代码就跟个傻子一样来一次请求算一次答案硬生生把自己变成了“复读机”。作为一名每天在一线高频处理微信及企微 API 接口机器人客户问题的销售客服看到这种因为没搞懂“消息幂等”而造成的运营车祸我真是一头雾水又替他们捉急。很多研发眼里只有“收”和“发”根本没有防重试的底层思维。今天咱们别扯虚的直接基于星云API xingyapi.com的底层通信架构带你死磕“消息幂等”这个硬核逻辑。把clientMsgId怎么用彻底盘明白让你的机器人再也不犯抽。什么是幂等为什么你的机器人会变“复读机”企微的底层网关有一个死铁律不管是给你推 Webhook还是你调接口发消息只要 5 秒内没收到明确的 HTTP 200 成功响应网关就会认为网络断了然后立刻发起疯狂重试。如果你的代码处理得慢比如查库慢、调大模型慢第一个请求还没处理完第二个、第三个重试请求就砸过来了。如果不做拦截你的系统就会把同一条提问处理 3 遍自然就回了 3 遍。所谓的“幂等”就是保证不管同一个请求被重试了多少次业务逻辑永远只执行一次。防御第一道防线接收侧基于 MsgId 的秒级去重在防复读机的战役中第一步是“防接收重复”。 当你配置好 Webhook 后客户每发一条消息网关推过来的 JSON 里都会带有一个全球唯一的身份标识——MsgId。实战 JSON 载荷提取去重特征码JSON{ MsgType: text, roomType: 2, ChatId: wr_xxxxxxxxxxxxxxxxxxxx, FromUserName: wm_xxxxxxxxxxxxxxxxxxxx, Content: 优惠券怎么领, MsgId: msg_xxxxxx_唯一的流水号_xxxxxx // 核心去重就靠它 }底层拦截逻辑大白话版收到这个 JSON 后第一行代码什么都别干先把MsgId拿出来去 Redis 里执行一个SETNX如果不存在则设置操作。如果 Redis 告诉你设置成功说明这是第一次收到这个消息放行去走业务逻辑。如果 Redis 告诉你已经存在了说明这是网关超时触发的重试请求直接 return success当做没看见把重试请求直接扔进垃圾桶。进攻的艺术发送侧利用 clientMsgId 确保不重发很多研发以为做好了接收侧的去重就万事大吉了错在主动调用 API 发消息的时候同样有重发风险。假如你的代码去调发消息接口消息其实已经成功发到客户手机上了但是在回传 HTTP 200 给你的瞬间机房网络闪断了。你的代码以为发送失败于是又调了一次接口。得客户又收到了两遍。为了解决这个大坑你可以查阅 API文档 里的高级发送参数我们会用到client_msg_id这个防重利器。实战 JSON 载荷带防御盾的发消息JSON{ instance_guid: inst_xxxxxx, conversationId: wr_xxxxxxxxxxxxxxxxxxxx, msgtype: text, text: { content: 这是您的专属满减优惠券链接... }, client_msg_id: req_1698765432_随机数 // 你自己生成的业务流水号 }防重底层原理这个client_msg_id是你自己生成的可以用时间戳加随机数或者关联你们内部的订单ID。 当你带上这个参数打给网关时底层会把它缓存一小段时间。如果你因为代码重试短时间内又传了同一个client_msg_id过来网关会直接返回成功但绝对不会向客户再下发一次真实的微信消息。这就把重发风险死死按在了底层网关上。老司机的排障防坑铁律幂等逻辑最大的难点在于它是一种“保护机制”平时网络好的时候你根本感觉不到它的存在一旦高并发或者大促网络拥堵没有它你的系统瞬间原形毕露。所以千万别在生产环境当小白鼠去测幂等我强烈建议各位研发兄弟在写这套防重机制的时候必须祭出Apifox或者Apipost这类接口调试神器本地起好你的 Webhook 接口连上本地的 Redis。在 Apifox 里捏造一个带MsgId的 JSON 报文。关键操作利用 Apifox 的并发测试功能针对同一个 JSON瞬间发起 10 次并发请求盯着你的控制台和日志如果你的数据库里只存入了一条记录且只触发了一次大模型调用其他的 9 次全部被 Redis 挡住并直接返回了 success恭喜你你的去重铠甲打磨成功了。把接收侧的MsgId缓存拦截和发送侧的client_msg_id穿透防御结合起来你的机器人才算是真正具备了工业级的抗压能力。大家在写分布式锁或者组装随机数去重的时候如果卡壳了随时在评论区贴出你的代码片段咱们接着盘
返回列表