华为云 API 网关限流防刷实战:用三道闸门守住接口入口
接口不怕没人用,就怕被"用过头"。一次突发流量或恶意刷单,就足以把下游数据库拖垮。限流不是可选项,而是底线。
一、没有限流的系统,全靠运气
很多接口上线时是"裸奔"的:没有频率控制,也没有并发上限。平时风平浪静,一旦撞上爬虫、秒杀活动,或者某个客户端 bug 死循环调用,请求就像洪水一样涌进来——数据库连接池率先被打满,紧接着整个服务雪崩。
限流的意义正在于此:宁可主动拒绝一部分请求,也要保住整体可用。丢掉几十个请求,总比全线崩掉强得多。
二、先理解令牌桶
最常用的限流算法是令牌桶:系统以固定速率往桶里放令牌,请求到达时先取令牌,取不到就拒绝或排队。它允许一定程度的突发(桶里攒下的令牌),流量控制比固定窗口更平滑,也更贴近真实业务。固定窗口计数虽然实现简单,但在窗口切换的临界点会出现"双倍突发",实际效果往往并不理想。想清楚这一点,后面选策略就不容易踩坑。
三、华为云 APIG 的三道闸门
在 API 网关(APIG)上做限流,通常分三层,层层设防:
- 基础流控:在 API 维度设置单位时间内的调用上限,粒度最粗、也最常用;
- 参数流控(精细化流控):按 Header、Query、路径参数等维度限流,例如"每个用户每小时最多 100 次",特别适合防刷;
- 插件级限流:通过限流插件对绑定该插件的所有 API 统一控制,适合做整站级的兜底。
三层叠加的原则是:越靠近用户越精细,越靠近后端越兜底。不要指望一层就挡住所有场景。
四、客户端必须配合:优雅处理 429
服务端限流后返回的是 429 Too Many Requests。客户端若拿到 429 就疯狂重试,无异于火上浇油。正确做法是指数退避 + 随机抖动:
import time, random, requests
def call_with_backoff(url, payload, max_retry=5):
for i in range(max_retry):
resp = requests.post(url, json=payload, timeout=5)
if resp.status_code != 429: # 未被限流,直接返回
return resp
backoff = min(2 ** i, 30) # 指数退避,封顶 30s
time.sleep(backoff * (0.5 + random.random())) # 加抖动,避免集体重试
raise RuntimeError("限流重试次数已耗尽")
抖动那一步很关键:没有随机性,所有客户端会在同一时刻集体重试,反而形成第二波洪峰。
五、实战避坑清单
- 阈值靠压测得出:限流值不能拍脑袋,要根据下游数据库、缓存的实际承载能力反推,宁紧勿松。
- 区分 429 与 503:429 表示"你太快了",重试有效;503 表示"我扛不住了",应配合熔断降级,别一视同仁。
- 给突发留余量:令牌桶的容量决定突发容忍度,秒杀类场景要留空间,否则正常用户也会被误伤。
- 限流维度别选错:按 IP 限流会误伤 NAT 后的整栋楼用户,按用户或 API Key 更精准。
- 和监控联动:把限流触发次数接入 CES 监控并设置告警——突增往往意味着被刷或客户端异常,必须能第一时间发现。
六、小结
限流的核心思想一句话就能概括:用可控的拒绝,换取整体的稳定。服务端靠 APIG 的三层闸门守住入口,客户端靠指数退避优雅退让,再配上监控告警,才能真正把"被打挂"的风险挡在门外。别等雪崩了,才想起加限流。
- 点赞
- 收藏
- 关注作者
评论(0)