使用 Redis 解决钉钉机器人报警频率限制
需求
因为服务化拆分之后,数据的最终一致性没有做好,导致业务生成很多脏数据
。因此需要额外增加很多脚本,做数据检查监控,监控结果需要及时发送钉钉。正常情况下,每天的异常消息不会很多,但是每次因为新加脚本,需要扫所有历史数据,会很频繁地发送钉钉消息。
但是钉钉机器人发送频率限制是
20条/每分钟
,如果超过限制,会返回send too fast
错误信息,再发,就直接302
并限制发送10分钟
简单方案
合并消息为一条大的消息, 但是消息不能太大,实际最多几千字好像,数据太大也不能发送。
临时方案
简单的方案还是不能解决初始化历史数据,大量发送消息的问题。因为时间问题,最初想到的临时方案,是每次发送结束 sleep 3 秒钟,这样绝对不会超出限制。但是有很大的问题
- 导致正常运行时,发送后脚本效率变低
最终方案
由于 Redis 支持的类型丰富
,用法简单
,效率高
等特点, 且很多公司都会用到 Redis 无需额外安装。
解决思路是:
- 一个群最多申请六个机器人,把六个token保存在数组中
- 每次发送,依次查看每个token的 redis
sorted set
集合中以最近一分钟timestamp
为scope
范围的数量 - 如果大于 18,查询下一个token,否则是可用的token
部分代码如下:

最后有一步特殊处理,如果 6 个 token 都不可用,将消息保存在一个 set
集合中,有效期 7 天,这样总比消息丢失强,不过这种应该很少出现了。因为 6 个机器人,最多一分钟就可以发送 6 * 18 = 108 条消息了,如果是单进程脚本,每次执行发送间隔只小到 ~ 50 ms
, 已经基本能满足目前需要。
现在可以放心的把之前代码中,发送消息之后 sleep(3)
删除了
转载自:https://juejin.cn/post/6844903845932302350