钉钉机器人消息发送频率限制是多少怎么避免被限流

文章导读
钉钉自定义机器人默认每分钟最多发送 20 条消息到同一个群,一旦超限会被限流 10 分钟。生产环境必须通过代码层做消息聚合或轮询策略来规避,严禁直接丢弃关键告警。
📋 目录
  1. A 核心限制与错误码
  2. B 代码实现:消息聚合示例
  3. C 请求参数与安全配置
  4. D 限流后的降级策略
  5. E 验证与排查
  6. F 常见坑
  7. G 参考来源
A A

钉钉自定义机器人默认每分钟最多发送 20 条消息到同一个群,一旦超限会被限流 10 分钟。生产环境必须通过代码层做消息聚合或轮询策略来规避,严禁直接丢弃关键告警。

先说结论:单机器人单群每分钟限 20 条,超限封禁 10 分钟,错误码通常为 130101。

  • 先定位:检查业务日志中是否有 errcode 130101 或 HTTP 429 状态码。
  • 先做:代码层增加消息队列,将多条告警合并为一条 Markdown 发送。
  • 再验证:观察日志中限流错误是否消失,消息延迟是否在容忍范围内。

核心限制与错误码

钉钉机器人 API 针对“一个机器人和一个群的组合”进行频率限制。以下是关键参数与错误码对照,便于排查:

限制项阈值后果错误码/状态
发送频率20 条/分钟接口限流 10 分钟errcode: 130101
消息长度4000 字符发送失败errcode: 130106
并发限制视服务器负载请求超时HTTP 429/503

当接收到 130101 错误时,表示当前分钟配额已用完,必须立即停止发送并进入等待或降级流程。

代码实现:消息聚合示例

为避免频繁调用接口,建议在业务代码中维护一个缓冲队列。以下是一个简单的 Python 实现思路,演示如何攒批发送:

import time
import requests
import threading
from queue import Queue

# 配置 Webhook
WEBHOOK_URL = "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"

# 消息队列
msg_queue = Queue()

def send_batch():
    while True:
        batch_msgs = []
        # 策略:攒够 5 条 或 等待 5 秒
        start_time = time.time()
        while len(batch_msgs) < 5 and (time.time() - start_time) < 5:
            try:
                msg = msg_queue.get(timeout=1)
                batch_msgs.append(msg)
            except:
                break
        
        if batch_msgs:
            # 合并消息内容
            content = "## 告警汇总\n" + "\n".join(batch_msgs)
            payload = {
                "msgtype": "markdown",
                "markdown": {"title": "告警汇总", "text": content}
            }
            try:
                resp = requests.post(WEBHOOK_URL, json=payload)
                result = resp.json()
                if result.get("errcode") == 130101:
                    # 触发限流,将消息重新放回队列或写入持久化存储
                    for m in batch_msgs:
                        msg_queue.put(m)
                    time.sleep(60) # 强制等待
            except Exception as e:
                # 记录错误日志
                print(f"Send failed: {e}")

# 启动发送线程
threading.Thread(target=send_batch, daemon=True).start()

# 业务调用示例
msg_queue.put("- CPU 使用率过高:95%")
msg_queue.put("- 内存不足:剩余 100MB")

注意:生产环境建议使用 Redis 或数据库作为队列存储,防止进程重启导致消息丢失。

请求参数与安全配置

发送 POST 请求时,Content-Type 必须为 application/json,字符集编码设置为 UTF-8。若群机器人开启了“加签”安全设置,请求 URL 需携带 timestamp 和 sign 参数。

1. 基础 JSON payload 示例:

{
    "msgtype": "markdown",
    "markdown": {
        "title": "故障告警",
        "text": "## 故障告警\n- 服务:OrderService\n- 状态:DOWN\n- 时间:2023-10-27 10:00:00"
    },
    "at": {
        "isAtAll": true
    }
}

2. 加签配置说明:

如果后台开启了加签,URL 格式如下:

钉钉机器人消息发送频率限制是多少怎么避免被限流

https://oapi.dingtalk.com/robot/send?access_token=XXX×tamp=XXX&sign=XXX

sign 计算公式:使用 HMAC-SHA256 算法,将“timestamp + '\n' + 密钥”进行加密,再进行 URL Encode。

限流后的降级策略

捕获接口返回的错误码后,一旦发现限流(130101),严禁直接丢弃非关键消息,建议采取以下策略:

  1. 持久化缓存:将发送失败的消息写入本地日志、数据库或 Redis 队列。
  2. 指数退避:等待时间逐步增加(如 1 分钟、2 分钟、5 分钟)后重试。
  3. 关键告警通道分离:对于 P0 级故障,配置独立的机器人 Webhook 或切换至短信/电话通知渠道,避免被普通告警限流阻塞。

验证与排查

修改代码后,通过以下步骤验证优化效果:

  1. 日志监控: grep 业务日志中的"errcode"关键字,确认 130101 出现频率是否降为 0。
  2. 压力测试:在测试环境模拟高频告警(如 1 分钟 50 条),观察是否触发限流以及消息合并是否符合预期。
  3. 延迟检查:确认消息从产生到钉钉群接收的延迟是否在业务允许范围内(通常聚合会导致秒级延迟)。

常见坑

1. 消息长度超限:合并消息时注意总字符数不要超过 4000 字符,否则接口会直接报错。

2. Webhook 泄露:保管好 Webhook 地址,不要公布在外部代码仓库或前端代码中,泄露后有安全风险。

3. 安全设置不匹配:发起 POST 请求时,必须根据群机器人后台设置(关键词、加签、IP 白名单)配置对应参数,否则返回 401 错误。

4. 进程重启丢失:如果使用内存队列(如 Python list/Queue),服务重启会导致未发送消息丢失,生产环境务必使用持久化存储。

参考来源

  • 钉钉开放平台 - 自定义机器人发送群消息 - https://open.dingtalk.com/document/orgapp/custom-robots-send-group-messages
  • 钉钉开放平台 - 错误码对照表