跳到主要内容

顺手记一下 GitLab.com 这次的速率限制变更,坑在未认证那 60 次

abanana
abanana

· 阅读约 5 分钟

上个月中旬 GitLab 发了篇博文,讲 GitLab.com 的速率限制要怎么调。我当时扫了一眼标题就划过去了,心想我又不刷 API,跟我有什么关系。前几天翻一个定时脚本的运行日志,发现响应头里多了几个没见过的字段,才回头把原文和速率限制文档一起翻了一遍。

先说这篇要记的东西:这次调整里真正会突然卡人的,不是 Free 还是 Premium 的问题,是那条「未认证请求按每个 IP 每小时 60 次」。判断依据是你带没带凭据,不是你账户什么等级——这两件事很容易混,我一开始也混了。

时间线摆一下。限制按订阅层级对齐,Free 和未认证的先动,10 月 19 日;Premium 和 Ultimate 往后推到 2027 年 1 月。限制按用户和顶级群组两个维度分别适用,已认证请求走你订阅计划对应的额度,具体数值在速率限制文档里能查到。未认证请求则一律按每 IP 每小时 60 次算,这条不看来源,也不看你背后挂的是不是付费账户。

原文里有一句写得很清楚:针对付费账户运行、但没提供凭据的自动化,一样受匿名额度约束。所以那些把脚本挂在某个 Premium 群组下、却从来没配过 token 的同学,10 月 19 日之后很可能第一个撞墙。

博文里提到两个「预览窗口」,10 月 7 日和 10 月 14 日的 15:00 到 19:00 UTC,官方管这个操作叫 brownout,做法是短时把新限制开起来,跑几个小时再关掉。我第一反应以为这是「限制放宽的窗口」,可以趁这段时间多跑点东西——后来才反应过来正好相反,这是在正式生效前拿真实流量试一遍,看看会炸出什么。💡 所以这两个窗口反而是最有价值的验证时机,拿你自己的自动化在里面跑一轮:

for i in $(seq 1 30); do
  curl -s -o /dev/null -D - \
    "https://gitlab.com/api/v4/projects/<id>/issues" \
    | grep -i ratelimit-remaining
done

在窗口里跑,看到的才是新额度下的消耗速度;窗口之外跑,响应头里的数字还是旧口径,参考价值有限。已认证的 Premium 和 Ultimate 请求不受这两个窗口影响,因为它们的限制 2027 年 1 月之前不变,这也侧面说明窗口是专门为 Free 和匿名流量准备的。

日常体检的话,不管什么时候都可以看一眼剩余额度:

curl -sI -H "PRIVATE-TOKEN: $TOKEN" \
  https://gitlab.com/api/v4/user | grep -i ratelimit-remaining

RateLimit-Remaining 是最直接的窗口剩余量,比事后翻日志猜要快得多。官方也提到 2026 年晚些时候会上一个产品内的用量视图,能看到当前用量和计划限制的对比,那之前就先靠这个头。

真触到限制了,服务端返回 HTTP 429,同时带一组 RateLimit-* 头和一个 Retry-After 头:

HTTP/2 429
retry-after: 47
ratelimit-limit: 60
ratelimit-remaining: 0

Retry-After 给的是需要等多久。这时候立刻重试是最差的处理方式,本身就在往已经满了的窗口里继续塞请求;指数退避恢复得更快。这一段我是踩过一次才记住的,当时写了个「失败就马上重试」的循环,结果把匿名额度一直摁在零上,等了比应该等的久得多。

想少消耗额度,做法其实都是老套路:批处理、缓存、分页,别在紧密循环里轮询。这次被卡住的典型场景恰好就是最后一条——为了等某个状态变化,每隔几秒 poll 一次接口。改成按指数退避拉长间隔,或者合并成一次列表查询,消耗立刻降下来。

认证方式这块,个人访问令牌、OAuth 令牌、CI/CD 作业令牌都可以。CI job token 那条值得单独说一句:GitLab CI 里这个 token 是自动注入到环境变量里的,但如果你的脚本是手写的 curl、没把它带上,请求就悄悄退回匿名额度了。这个坑我见过不止一次,-H 那一行漏掉,跑 CI 的时候一切正常,因为额度还没用完,等哪天量上来了才发现一直在用匿名配额。

公开且繁忙的项目稍微麻烦一点。可行做法有几个:让调用的自动化登录、把项目改成私有,或者升级到 Premium/Ultimate。官方也提到公开状态徽章属于合法的匿名模式,不用为了它单独配凭据——这个细节我挺喜欢,说明不是要把所有匿名请求都赶尽杀绝,只是不想让单一工作负载拖慢整个平台。

另外两点容易搞混的边界,顺手记一下。

这个变更只作用于 GitLab.com,Self-Managed 和 GitLab Dedicated 的限制仍由各自的运维方管,别把这篇的结论套过去。还有,如果你同时是多个顶级群组的成员,用户维度取的是可用的最高订阅层级——属于一个 Ultimate 群组,就能用 Ultimate 的限制。

划重点:第一,判断依据是请求有没有带凭据,不是账户等级,这条比记住具体数字重要;第二,10 月 7 日和 10 月 14 日的两个预览窗口是免费的实弹演练,拿自己的脚本进去跑一轮,比看公告有用;第三,RateLimit-Remaining 头随时可查,把它加进你的日志,出问题的时候能省很多猜的时间;第四,429 之后先看 Retry-After,退避重试,别原地死磕。你可以照着自己手上跑得最勤的那个脚本试一遍,如果发现别的坑,欢迎回来留言,我一起补一条。

abanana
abanana

把自己踩过的坑整理成一篇能复现的笔记,写给三个月前的自己看。

查看主页 →