API 使用限制
本文适用于 RTM 2.x 客户端 SDK 和 RESTful API,介绍各层级的使用限制、超出限制后的行为,以及容量规划时的估算方法。
快速导航
| 使用场景 | 参考章节 |
|---|---|
| 调用返回了限频错误 | 调用频率限制 |
| 发送失败,提示消息过长或参数超限 | 消息规格 |
| 频道人数增加后延迟上升、用户反复重连 | 频道消息速率建议值、场景示例 |
| 上线前估算容量 | PCU 估算、频道消息速率建议值、场景示例 |
| 想申请提高某个上限 | 申请提升与提前沟通 |
限制层级
RTM 的限制分为四层。上层限制约束总量,下层限制约束单个对象;同一次调用可能同时受到多层限制。
| 层级 | 作用对象 | 超出后怎么发现 | 章节 |
|---|---|---|---|
| 账号级 | 你的声网账号 | RESTful API 返回配额错误 | 第 1 章 |
| 项目级(App ID) | 单个项目 | 多数为建议值,超出前需联系技术支持 | 第 2 章 |
| 频道级 | 单个频道 | 容量类返回错误;速率类为建议值 | 第 3 章 |
| 客户端级 | 单个 RTM 客户端实例 | SDK 错误回调 | 第 4 章 |
限制类型
| 类型 | 含义 | 超出后 | 可否调整 |
|---|---|---|---|
| 固定上限 | 系统硬性约束 | 调用失败并返回错误 | 否 |
| 默认上限 | 默认配额 | 调用失败并返回错误 | 可申请提升,见第 9 章 |
| 建议值 | 在此范围内可获得最佳性能 | 通常不报错 | 建议超出前联系技术支持 |
| 不限数量 | 资源数量不设上限 | — | 不代表容量无限,仍受速率和吞吐约束 |
1. 账号级限制
| 限制项 | 数值 | 类型 | 说明 |
|---|---|---|---|
| RESTful API 总调用速率 / 账号 | 1000 次/秒 | 默认上限 | 账号下所有项目、所有 RESTful API 合计;超出返回 HTTP 429。 |
2. 项目级限制(App ID)
| 限制项 | 数值 | 类型 | 说明 |
|---|---|---|---|
| 峰值同时在线用户数(PCU) | 20 万 | 建议值 | 预计超过时请提前联系技术支持。估算方法见2.1。 |
| 总上行消息速率 | 10 万条/秒 | 建议值 | 项目下所有客户端和 RESTful API 发送量合计。 |
| Message Channel 数量 | 不限数量 | 不限数量 | 频道随用随取,无需预先创建。 |
| Stream Channel 数量 | 不限数量 | 不限数量 | 频道随用随取,无需预先创建。 |
| Channel Metadata 总量 | 100 万 | 建议值 | 预计超过时请提前联系技术支持。 |
| User Metadata 总量 | 100 万 | 建议值 | 预计超过时请提前联系技术支持。 |
| Lock 总量 | 100 万 | 建议值 | 预计超过时请提前联系技术支持。 |
| 历史消息存储时长 | 1、7、30、90、365 天或永久 | 默认上限 | 在控制台按项目配置。已写入消息的保存时长不受后续配置影响。 |
2.1 怎么估算你的 PCU
RTM 的限制和计费都以 PCU 为单位,而业务指标通常只有 DAU、房间数或课堂数。按业务形态选择对应的估算方法:
| 业务形态 | 你已有的数据 | PCU 估算公式 |
|---|---|---|
| IM / 社交 | DAU、用户日均在线时长 | PCU ≈ DAU × 日均在线时长 ÷ 24 小时 × 峰值系数 |
| 直播 / 秀场 | 同时开播房间数、单房间平均观众数 | PCU ≈ 同时开播房间数 × 单房间平均观众数 × 峰值系数 |
| 教育 / 会议 | 同一时段的课堂数、每场人数 | PCU ≈ 同一时段课堂数 × 每场人数 |
| 游戏 | 同时在线玩家数(CCU) | PCU ≈ CCU |
峰值系数用于把日均值放大到峰值时段,经验上取 2–3。有明确活动峰值的业务(例如大促、赛事、开学)请直接按活动峰值估算,不要使用日均值。
常见的估算偏差包括:
- 多端登录按多个连接计。同一用户同时在手机和网页登录时,PCU 计 2。
heartbeatInterval会影响 PCU。心跳间隔越长,掉线用户被判定离线越慢,统计出的 PCU 越偏高。默认值为 5 秒,范围为 5–1800 秒。
3. 频道级限制
3.1 容量
| 限制项 | 数值 | 类型 | 说明 |
|---|---|---|---|
| Message Channel 订阅者数(未开启 Presence) | 不限数量 | 不限数量 | 仍受3.2 的消息速率建议值约束。 |
| Message Channel 订阅者数(开启 Presence) | 5000 人 | 建议值 | 预计超过时请提前联系技术支持。 |
| Message Channel 发布者数 | 不限数量 | 不限数量 | — |
| Stream Channel 在线用户数 | 128 人 | 固定上限 | 第 129 人 join 失败并返回错误码。需要更大规模时使用多个 Stream Channel 或改用 Message Channel。 |
| Stream Channel 内 Topic 数 | 不限数量 | 不限数量 | Topic 随首个发布者加入创建,最后一个发布者离开后销毁。 |
| 频道内锁数量 | 32 把 | 建议值 | 预计超过时请提前联系技术支持。 |
3.2 频道消息速率建议值
频道消息速率是每秒内所有发布者(客户端和 RESTful API)向同一个频道发送的消息总条数。它是频道级限制,与第 4 章的客户端级限频分别计算:每个客户端都没有超限时,频道合计仍可能超出建议值。
建议值随频道同时在线人数分档。人数越多,每条消息的扇出成本越高,频道能承受的速率越低。
| 单个频道同时在线人数 | 频道消息速率建议上限 |
|---|---|
| < 1,000 | 200 条/秒 |
| 1,000–10,000 | 100 条/秒 |
| ≥ 10,000 | 30 条/秒 |
超出后的表现:通常不报错,但延迟可能增加,消息可能丢失,用户可能无法收发消息或反复重连。
接近建议值时:
- 按用户分片到多个频道,每个频道独立对照上表。
- 高频小消息改用 Stream Channel + Topic(单频道不超过 128 人)。
- 在业务服务端聚合后通过 RESTful API 发送,减少上行条数。
- 需要更高速率时提前联系技术支持,可在不影响延迟和稳定性的前提下定制提升。
4. 客户端级限制
以下限制均以单个 RTM 客户端实例为统计单位,多个客户端各自独立计算。
4.1 调用频率限制
RTM 将客户端 API 按功能分为若干操作类别,每个类别拥有独立的每秒调用配额。同一类别内的方法共享配额,不同类别之间互不影响。例如,同一秒内调用 15 次 whoNow 和 15 次 getChannelMetadata 不会触发限频,因为它们属于不同类别;但同一秒内调用 25 次 whoNow 会触发限频。
超出配额的调用不会被执行,也不会排队。SDK 通过错误回调返回限频错误码,需要在业务层节流或退避后重试,见第 8 章。
有特殊配额的操作
| 操作类别 | 方法 | 配额 / 客户端 | 类型 | 说明 |
|---|---|---|---|---|
| 发送消息 | publish | 60 次/秒 | 默认上限 | Message Channel 与 User Channel 共用这 60 次。 |
| 发送 Topic 消息 | publishTopicMessage | 200 次/秒,按单个 Stream Channel 计 | 默认上限 | 同一客户端加入多个 Stream Channel 时各自独立,不占用其他类别配额。 |
| 修改频道属性 | setChannelMetadata、updateChannelMetadata、removeChannelMetadata | 20 次/秒 | 默认上限 | — |
| 读取频道属性 | getChannelMetadata | 20 次/秒 | 默认上限 | — |
| 修改用户属性 | setUserMetadata、updateUserMetadata、removeUserMetadata | 20 次/秒 | 默认上限 | — |
| 读取用户属性 | getUserMetadata | 20 次/秒 | 默认上限 | — |
| 获取锁 | acquireLock | 10 次/秒 | 默认上限 | — |
其余操作:每个类别各 20 次/秒
下表每一行是一个独立类别,行内的方法共享该类别的 20 次/秒配额。
| 类别 | 方法 |
|---|---|
| 登录 | login |
| 更新 Token | renewToken |
| 订阅 Message Channel | subscribe |
| 加入 Stream Channel | join、leave |
| 加入 Topic | joinTopic、leaveTopic |
| 订阅 Topic | subscribeTopic |
| 订阅用户属性 | subscribeUserMetadata |
| 查询频道在线用户 | whoNow |
| 查询用户所在频道 | whereNow |
| 修改临时状态 | setState |
| 读取临时状态 | getState |
| 设置锁 | setLock |
| 删除锁 | removeLock |
| 释放锁 | releaseLock |
| 撤销锁 | revokeLock |
| 查询锁 | getLocks |
| 获取历史消息 | getMessages |
4.2 连接与实例
| 限制项 | 数值 | 类型 | 超出后 |
|---|---|---|---|
| RTM 实例数 / 客户端 | 1 个 | 固定上限 | 创建第 2 个实例失败。 |
userId 长度 | 64 个 ASCII 字符 | 固定上限 | 初始化或登录失败。 |
| 同时订阅 Message Channel 数 | 50 个 | 默认上限 | 第 51 次 subscribe 失败并返回错误码。 |
| 同时加入 Stream Channel 数 | 10 个 | 默认上限 | 第 11 次 join 失败并返回错误码。 |
| 同时加入 Topic 数 / 频道 | 8 个 | 固定上限 | 第 9 次 joinTopic 失败。 |
| 同时订阅 Topic 数 / 频道 | 50 个 | 固定上限 | 第 51 次 subscribeTopic 失败。 |
| 订阅发布者数 / Topic | 64 个 | 固定上限 | 不传 users 时随机订阅至多 64 个发布者,超出的发布者消息收不到。 |
4.3 消息规格
| 限制项 | 数值 | 类型 | 超出后 |
|---|---|---|---|
| 消息包体积(Message / User Channel) | 32 KB | 默认上限 | 发送失败,错误码 -11010。体积 = 消息负载 + customType。 |
| 消息包体积(Topic) | 1 KB | 默认上限 | 发送失败,错误码 -11010。计算方式同上。 |
customType 长度 | 32 个 ASCII 字符 | 固定上限 | 发送失败。 |
| 频道名长度 | 64 个 ASCII 字符 | 固定上限 | 调用失败;另受合法字符集约束,参见频道命名指南。 |
| Topic 名长度 | 16 个 ASCII 字符 | 固定上限 | 调用失败。 |
getMessages 单次条数 | 100 条 | 固定上限 | 超出部分需翻页获取。 |
getMessages 查询窗口 | start 与 end 间隔不超过 24 小时 | 固定上限 | 调用失败并返回错误码。 |
4.4 Presence 规格
| 限制项 | 数值 | 类型 | 超出后 |
|---|---|---|---|
presenceTimeout | 默认 300 秒,范围 5–300 秒 | 固定范围 | 不报错,就近取边界值。例如传 400 秒时按 300 秒生效。 |
| 临时状态键值对数 / 用户 / 频道 | 32 对 | 固定上限 | setState 失败。 |
| 临时状态单个 value 大小 | 16 KB | 固定上限 | setState 失败。 |
| 临时状态 key 长度 | 32 个 ASCII 字符 | 固定上限 | setState 失败。 |
| 加入频道前可缓存的临时状态数 | 100 个 | 固定上限 | 加入或订阅后才生效并触发通知。 |
whoNow 单页人数 | 100 人 | 固定上限 | 通过 nextPage 翻页。 |
| 实时通知最大人数(Announce → Interval 切换阈值) | 默认 50 人,控制台可设 8–128 人 | 默认上限 | 在线人数达到阈值后,事件由实时通知改为周期聚合通知。 |
4.5 Storage 规格
| 限制项 | 数值 | 类型 | 超出后 |
|---|---|---|---|
Metadata Item key 长度 | 32 个 ASCII 字符 | 固定上限 | 调用失败。 |
| Metadata 组数 / 频道或用户 | 1 组 | 固定上限 | — |
| Metadata Item 数 / 组 | 不限数量 | 不限数量 | 仍受整组 16 KB 约束。 |
| 单组 Metadata 大小 | 16 KB | 默认上限 | 写入失败。 |
| 单个 Metadata Item 大小 | 16 KB | 默认上限 | 写入失败;与整组 16 KB 同时生效。 |
Metadata 写入后会长期保存,频道销毁或用户注销不会自动删除;不再需要时请显式删除。
4.6 Lock 规格
| 限制项 | 数值 | 类型 | 超出后 |
|---|---|---|---|
| 同时持有锁数 / 客户端 | 不限数量 | 不限数量 | — |
| 锁 TTL | 默认 10 秒,范围 10–300 秒 | 固定范围 | 不报错,就近取边界值。TTL 只在持有者掉线后开始计时;TTL 内重连回来仍持有锁,超时自动释放并触发事件。 |
| 锁名长度 | 64 个 ASCII 字符 | 固定上限 | 调用失败。 |
5. RESTful API 限制
| 限制项 | 数值 | 类型 | 说明 |
|---|---|---|---|
| 账号总调用速率 | 1000 次/秒 | 默认上限 | 返回 HTTP 429,见第 1 章。 |
publish 单频道速率 | 不单独设限 | — | RESTful API 发送量与客户端发送量一起计入3.2 的频道消息速率。 |
publish 消息包体积 | 32 KB | 固定上限 | 超出会报错。 |
publish 请求体 | 可序列化字符串 | 固定上限 | 不支持二进制请求体;二进制内容请先进行 Base64 编码。 |
| History 查询速率 | 60 次/秒 | 建议值 | 超出返回配额错误。 |
| History 单次条数 | 100 条 | 固定上限 | 超出部分翻页获取。 |
6. 场景示例:怎么对照 3.2 做规划
频道消息速率 ≈ 频道内活跃发布者数 × 人均每秒发送次数。先估算这个值,再对照3.2 的分档表。分档表第一列是同时在线人数(决定扇出成本),第二列是发送速率,两者分别估算。
以下规模数字仅为演示,请用真实埋点数据替换:
| 场景 | 示例规模 | 估算速率 | 对照 3.2 | 推荐做法 |
|---|---|---|---|---|
| IM 群聊 | 500 人群,活跃时 5% 的人每 10 秒发 1 条 | 500 × 5% ÷ 10 ≈ 2.5 条/秒 | < 1,000 人档,上限 200,余量充足 | 使用 Message Channel;开启 Presence 时注意 5000 人建议值。 |
| 直播间弹幕 | 5 万观众,1% 的人每 5 秒发 1 条 | 50,000 × 1% ÷ 5 = 100 条/秒 | ≥ 10,000 人档,上限 30,超出 3 倍以上 | 在业务服务端聚合,每秒合并为不超过 30 条后通过 RESTful API 下发,或按观众分片到多个频道;礼物等低频高价值消息单独使用一个频道。 |
| 直播间礼物 / 系统通知 | 5 万观众,每秒不超过 5 条 | 5 条/秒 | ≥ 10,000 人档,上限 30,可承受 | 与弹幕分频道,避免被弹幕挤占。 |
| 多人游戏状态同步 | 100 人房间,每人每秒 10 次位置上报 | 1,000 条/秒 | Message Channel 任何档位都超出 | 使用 Stream Channel + Topic;单频道不超过 128 人,每个发布者不超过 200 次/秒,接收端按需订阅不超过 64 个发布者。 |
| IoT 设备上报 | 2,000 台设备,每台每 5 秒上报 1 次 | 400 条/秒 | 1,000–10,000 人档,上限 100,超出 4 倍 | 按设备分组到至少 5 个频道,每频道不超过 400 台、80 条/秒。 |
| 协同编辑 / 白板 | 20 人协作,每人每秒 20 次笔画事件 | 400 条/秒 | < 1,000 人档,上限 200,超出 2 倍 | 使用 Stream Channel + Topic;Topic 消息不超过 1 KB,客户端合并 50 毫秒内的笔画后再发送。 |
两个提醒:
- 活跃比例和人均频率对结果影响最大,优先用真实数据替换示例值。
- 分档表描述的是单个频道;分片后每个频道独立对照分档表,但项目级总上行速率(10 万条/秒,第 2 章)仍按所有频道合计。
7. 常见问题
不是。限频按操作类别分别计算,20 次/秒是单个类别的默认配额。发送消息的 60 次/秒不占用其他类别的配额,反之亦然。
不是。Message Channel 和 User Channel 的 publish 共用同一个 60 次/秒配额。
客户端限频只是第一层。频道另有消息速率建议值(3.2),项目另有总上行 10 万条/秒(第 2 章)。多个客户端同时向一个频道高频发送时,单个客户端都没超限,频道合计仍可能超出建议值。
不是。200 次/秒按单个 Stream Channel 计算;同一客户端加入多个 Stream Channel 时各自独立。
不会。超出配额的调用不会被执行,SDK 返回错误,需要业务层重试。
“不限数量”只说明人数不设限,频道仍受 3.2 的消息速率建议值约束;开启 Presence 后,5000 人以上请提前联系技术支持。
不能。128 人是固定上限。需要更大规模时使用多个 Stream Channel 或改用 Message Channel。
Item 数量不设限,但整组 Metadata 和单个 Item 各受 16 KB 约束,两者同时生效。
没有这个单独限制。RESTful API 发送量与客户端发送量一起计入 3.2 的频道消息速率,RESTful API 本身受账号级 1000 次/秒约束。
不会。TTL 内重新回到频道仍持有该锁;超过 TTL 才自动释放并触发事件。
8. 超出限制后怎么办
| 超限类型 | 怎么发现 | 要不要重试 | 建议做法 |
|---|---|---|---|
| 客户端类别配额超限(4.1) | SDK 错误回调,限频错误码 | 要 | 业务层做队列节流,指数退避后重试;不要在回调里立即重发。 |
| 容量类固定上限(体积、长度、数量) | SDK 错误回调,例如 -11010 消息过长 | 不要 | 修正参数后再调用;发送前本地校验体积。 |
参数范围类(presenceTimeout、锁 TTL) | 不报错,SDK 就近取边界值 | — | 按文档范围传值,不要依赖截断行为。 |
| 频道消息速率建议值(3.2) | 不报错;延迟大幅上升,用户无法收发或反复重连 | — | 按 3.2 分片频道或改用 Stream Channel;需要更高值时联系技术支持。 |
| 项目级建议值(PCU、总上行速率) | 不报错 | — | 预计超过时提前联系技术支持。 |
| RESTful API 配额超限 | HTTP 响应返回配额错误 | 要 | 服务端限流并进行退避重试。 |
限频错误的重试模式(各平台 SDK 的回调形式见对应 API 参考):
send(msg):
result = rtm.publish(channel, msg)
if result.error == RATE_LIMITED:
delay = min(baseDelay * 2^attempt, maxDelay) // 100 ms 到 2 s
wait(delay)
attempt += 1
if attempt < maxAttempts:
send(msg)
else:
report("publish dropped after retries")
else:
attempt = 0
更稳妥的做法是在发送侧维护一个按类别的令牌桶(发消息 60 次/秒、其他类别 20 次/秒),从源头避免触发限频,而不是依赖重试。
9. 申请提升与提前沟通
以下项目可以申请提升或需要提前沟通。请联系 rtm-support@agora.io 或技术支持,并附上 App ID、预计规模和上线时间:
| 项目 | 默认值 | 类型 |
|---|---|---|
| RESTful API 总调用速率 / 账号 | 1000 次/秒 | 申请提升 |
| PCU / 项目 | 20 万 | 超出前提前沟通 |
| 总上行消息速率 / 项目 | 10 万条/秒 | 超出前提前沟通 |
| 开启 Presence 的频道订阅人数 | 5000 人 | 超出前提前沟通 |
| 频道消息速率 | 见 3.2 分档表 | 可定制提升 |
| 同时加入 Stream Channel 数 / 客户端 | 10 个 | 申请提升 |
| 同时订阅 Message Channel 数 / 客户端 | 50 个 | 申请提升 |
publish 速率 / 客户端 | 60 次/秒 | 申请提升 |
publishTopicMessage 速率 / 客户端 / 频道 | 200 次/秒 | 申请提升 |
| 消息包体积 | 32 KB / 1 KB | 申请提升 |
| 单组 Metadata 大小 | 16 KB | 申请提升 |
| 频道内锁数量 | 32 把 | 申请提升 |
| Lock 总量 / 项目 | 100 万 | 申请提升 |