钉钉机器人消息幂等性主要靠发送端控制,建议在业务代码中结合 Redis 唯一键实现防重。适用场景为告警通知、状态变更推送,风险边界在于 Redis 不可用时需决定是阻断发送还是降级放行。
先说结论:钉钉自定义机器人 webhook 接口本身不提供消息去重能力,必须在发送端业务逻辑中实现幂等控制。
- 适合:告警系统、订单状态通知、定时任务结果推送
- 先看:业务唯一标识生成规则、Redis 键过期时间设置
- 建议:采用 setnx 原子操作加锁,超时自动释放避免死锁
快速处理思路
没有单一命令可解决,需按以下逻辑改造代码:
- 生成业务唯一 key(如 alert_type + business_id + timestamp_minute)
- 请求 Redis 执行 setnx key 1 EX 300
- 返回成功则调用钉钉 webhook,返回失败则跳过发送
为什么会这样
钉钉自定义机器人 webhook 接口设计为无状态 HTTP 请求,平台侧主要限制频率而非内容去重。
网络波动导致客户端重试、业务逻辑多次触发、定时任务重复执行都会产生重复消息。公开资料中没有看到可靠的量化数据说明平台侧去重机制,因此默认需要发送端自治。
分步处理
步骤 1:定义幂等键规则
组合业务场景码和实体 ID,例如 monitor:alarm:cpu_high:server_001:202310271000。确保同一告警事件在同一时间段内 key 一致。
步骤 2:实现原子检查
使用 Redis 的 SET 命令带 NX 和 EX 参数。代码示例逻辑:if redis.set(key, "1", nx=True, ex=300): send_dingtalk()。
步骤 3:处理发送失败
如果钉钉接口返回失败,不要立即删除 key,等待过期自然释放,防止短时间内重试风暴。
怎么验证是否生效
查看钉钉群聊记录,同一业务事件在过期时间内只出现一条消息。检查应用日志,确认第二次触发时命中了 Redis 存在判断并跳过了发送逻辑。
常见坑
1. 键过期时间过短:导致同一事件在不同分钟被判定为新事件,需覆盖事件完整生命周期。
2. 键生成规则不唯一:不同事件生成了相同 key,导致漏发通知。
3. Redis 集群故障:需设计降级策略,决定是停止通知还是允许重复通知。
常见问题
钉钉机器人支持 out_msg_id 去重吗?
自定义 webhook 机器人不支持,工作通知应用消息支持。
Redis 挂了会影响业务吗?
会影响幂等控制,需提前配置降级开关允许直发或阻断。
参考来源
钉钉开放平台 - 自定义机器人接入
https://open.dingtalk.com/document/robots/custom-robot-access