自动续期脚本今天突然不干活了:ACME 证书签发报 429,提示 too many certificates。距离续期还有大半个月,证书也没过期,问题出在限速(rate limit)上。限速不是故障,它更像高速公路的收费站:平时不起眼,但你想在高峰期一口气发完一百次请求时,它就会把你拦下来。本文直接从 Let's Encrypt 官方限速文档出发,讲清楚哪些限制最容易被踩、报错怎么看、重试等多久,以及怎么用 ARI 续期让自己少排队。

一、先分清:rate limit 报错长什么样
ACME 客户端(例如 Certbot、acme.sh)报限速时,错误消息并不统一。下面是官方文档的格式示例,不是本文刚执行得到的故障日志;其中 1970 年日期仅用于演示:
text
too many new registrations (10) from this IP address in the last 3h0m0s,
retry after 1970-01-01 00:18:15 UTC.
这句话很诚实:它直接告诉你有多少个请求、在哪个时间窗内、什么时候可以重试。同时,Let's Encrypt 的所有限速响应的 HTTP 响应头里都会带 Retry-After,这是最硬气的等待依据。需要注意:这个时间戳是 UTC,换算成本地时间别少算 8 小时。
一个常见误区:限速按请求计算,撤销证书根本不会重置限速。因为签发那杯水已经倒出去了,撤销只是把杯子还回来,收费站不会因此少收一次过路费。
二、最容易踩的坑:全局签发限制
两类限制是「全局」的------不管你是哪个账户、哪台机器,只要在一个注册域下申请就统一计入。理解这一点很关键,因为它意味着多账户、多客户端并不能绕开。
| 限制名称 | 额度 | 恢复速度 | 作用范围 |
|---|---|---|---|
| 每注册域证书数 | 50 张 / 7 天 | 约 202 分钟补充 1 张 | 全局(所有账户共享) |
| 每精确标识集合证书数 | 5 张 / 7 天 | 约 34 小时补充 1 张 | 全局(所有账户共享) |
注意「精确标识集合」:证书里包含的域名列表本身就是一个集合。比如 example.com + login.example.com 算一个集合,明天再签同样的组合,哪怕域名一模一样,因为内容相同,5 张的额度照样消耗。这个限制通常只有开发阶段容易撞上:反复重装客户端、每次部署都删掉 ACME 配置数据、对着一个报错来回折腾,都能把 5 张额度迅速吃光。官方文档的解释也是这个------它是专门为防「开发期反复重试」设计的上限。
那 50 张/7 天的注册域限制呢?它覆盖所有子域,哪怕你分别签 www、api、blog、shop 十几个子域名的证书,都往这 50 张额度里扣。绝大多数运维场景远远用不完,但大型站点集群、多环境频繁重建的团队可能会碰到。
三、账户与地址级限制:订单数和注册数
每一张证书都会创建一次订单(new-order)。新订单按账户计数,新账户注册则按来源地址或地址段计数:
| 限制 | 额度 | 恢复速度 |
|---|---|---|
| 每账户新订单数 | 300 次 / 3 小时 | 约 36 秒恢复 1 次 |
| 每 IP 新账户注册数 | 10 个 / 3 小时 | 约 18 分钟恢复 1 个 |
| 每 IPv6 /48 新账户注册数 | 500 个 / 3 小时 | 约 22 秒恢复 1 个 |
如果你用脚本在同一个机器上为「每个客户新建一个账户」这种设计,那「注册数」就是你要担心的第一道坎,10 个/3 小时很容易被几百个客户秒掉。官方给出的集成建议是反过来:一个账户服务多个客户,而不是一个客户一个账户。
四、验证失败类限制:5 次/小时只是开始
DNS-01、HTTP-01 验证失败同样有限制:同一账户对同一标识,每小时最多 5 次授权失败,额度每 12 分钟补充一次。这里还区分一条长期连续失败限制,不能把所有错误都塞进同一个重试循环。
同一账户对同一标识的连续授权失败上限为 1152 次;计数会按官方规则逐日恢复,验证成功会清零。超过限制后会暂停该账户为该标识申请证书,并在错误中提供官方自服务入口。它针对长期失败循环,不能忽略每小时额度,误算成"一晚上就能失败上千次"。先修复 DNS、网络或客户端逻辑,使用 staging 环境验证,再恢复生产申请。
五、负载均衡层的 503:整体请求限制
前面几类都是「签发语义」的限制,还有一类是纯粹的流量控制,由 ACME 服务入口的负载均衡器执行:
| 接口 | 每 IP 每秒请求数 | 突发容量 |
|---|---|---|
| /acme/new-nonce | 20 | 10 |
| /acme/new-order | 300 | 200 |
| /acme/new-account | 5 | 15 |
| /acme/revoke-cert | 10 | 100 |
| /directory | 40 | 40 |
超过这类限制时,响应码是 503 Service Unavailable 而不是 429,并且同样带 Retry-After。这类限制常见于「脚本忘了 sleep 就循环请求」或「几十台机器同一时间统一续期」的场景。缓解办法很简单:限制并发、错峰执行、给请求加退避重试。
六、重试策略:别急着冲,先算时间
所有限速消息都有固定的格式(超出多个限制时,返回「恢复最晚」的那一个)。等多久其实已经写死在消息里:
bash
# 从已存在的 Certbot 日志定位限速错误,不额外申请证书
grep -Ei 'rateLimited|too many|retry.after' \
/var/log/letsencrypt/letsencrypt.log
日志路径按实际安装方式调整;不要把带凭据的原始调试日志公开上传。要读取响应头,应使用 ACME 客户端保存的真实响应:new-order 需要合法账户和 JWS 签名,直接发一个裸 curl -X POST 既不是有效订单,也测不出账户剩余额度。Retry-After 可能是秒数或 HTTP 日期,应按客户端与响应的实际格式处理。
等待不是硬等。同样时间窗内,如果存在多个不同限制被触发,挑最晚的;如果只是验证失败,等 12 分钟再重试就能补回一次。最忌讳的是固定间隔无脑重试:比如每 2 分钟一次重试一小时,实际上触发了更多的失败计数,把自己推向更重的暂停。
七、进阶:用 ARI 续期,豁免限速
ACME Renewal Info(ARI)是官方推出的续期协调机制:客户端先询问服务端「我这证书的最佳续期窗口是什么时候」,等到窗口到达,再带着「我要替换哪张证书」去下订单。ARI 续期享受特殊待遇------不受任何限速约束。
关键不是客户端叫什么,而是当前版本是否真正实现并使用了 ARI。官方条件包括:新订单明确指出所替换的证书,至少一个标识与该证书匹配,且旧证书尚未通过 ARI 被替换过;完整行为应以客户端文档和运行日志核实,不能把普通 renew 命令直接当作 ARI 证据。没有 ARI 时,标识集合与旧证书完全一致(忽略大小写和顺序)的订单仍可能按旧逻辑识别为续期,豁免账户级新订单限制和注册域限制,但仍受精确标识集合、授权失败等限制。
这就是「续期几乎永不撞限速」背后的机制,也是官方特意把设计定成这样的原因:流量分摊自然错峰,绝大部分用户在实际经营中不会感知限速存在。
八、避坑清单与验收
- **先读错误消息:**里面有额度、时间窗和重试时间。
- 看响应头: 限速响应都会带
Retry-After,按它等最稳妥。 - **别反复重装删配置:**把 ACME 客户端配置目录反复删除重建,最容易吃光 5 张/周的精确集合额度。
- **测试走 staging:**staging 环境限速显著更高,修验证问题别占用生产额度。
- **多客户别多账户:**一个账户服务多个客户,才是官方建议的设计。
- **验证前先试 staging:**DNS-01 配置先切 staging 验证通过,再回生产。
- **紧急订单请求接口:**只有大规模场景才走官方调整表单,处理周期以周计,不是应急重置的手段。
最后不只看错误消失,还要确认订单完成、新证书有效期正确,并在部署后核验线上实际提供的证书。限速排查的重点不是"多试几次",而是读清错误、减少无效申请、让下一次重试有依据。