三道闸,三种人格
前两篇把网关闸(Nginx/SCG)与应用闸(注解切面)都装好了,加上数据库这道物理防线,系统里已有三层限流。三层如果各拍各的阈值,轻则互相打架(网关放行的流量被应用成批拒绝,网关白忙),重则全链路错位(内层闸形同虚设)。先把三道闸的人格分清楚:网关层挡的是「恶意与超额」——IP 刷子、CC 攻击、路由级总量,它看得见来源看不见业务;应用层管的是「配额与维度」——按用户、按商品、按方法的精确分配,它看得见业务;数据层是「保险丝」——连接池上限、慢查询超时,它不判对错,只在物理极限处熔断。
额度怎么分:外宽内紧
阈值分配的原则一句话:外层略宽于内层,越往外越宽容。以 503 咖啡馆下单接口为例,压测得出系统真实容量 2000 QPS,三层的数字这样定:
| 层 | 阈值 | 依据 | 拒绝谁 |
|---|---|---|---|
| 网关层 | 2200 QPS / 路由 + 单 IP 10 QPS | 容量 × 1.1 缓冲 | 恶意流量、明显超额 |
| 应用层 | 2000 QPS 总量 + 单用户 1 QPS | 压测拐点七折与业务规则 | 超额请求、违规配额 |
| 数据层 | 连接池 500 / 慢查询 1s 超时 | 物理极限 | 最后的异常突发 |
为什么外层反而宽?反过来想就明白:如果网关比应用紧,网关会误杀本可被系统消化的合法流量——应用层本来拦得住超额,网关抢着拦,拦错了还无从申诉;而网关比应用宽 10%,意味着「正常流量全都放得进来」,超出的余额由应用层精确裁决,网关只负责把明显恶意的挡在门外。外层是粗筛,内层是精判,粗筛永远不抢精判的活。
削峰填谷:让外层先排队
三层配合的第二个技巧是排队放外层,拒绝放内层。突发流量到达时,网关的 burst 队列(Nginx)先缓冲一小段——100 毫秒级的排队用户无感;队列满了才拒绝。应用层不排队,直接快速失败(有降级给兜底,第 13 篇);数据库层连失败都不给,直接连接超时。越往内层,等待的成本越高(线程、连接被占用),所以越往内越要快刀斩乱麻——「入口缓冲、内核快败」是多级限流的节奏口诀。
热点维度:秒杀的商品 ID
总量限流还有一个盲区:2000 QPS 的总量里,如果 95% 的流量都砸向同一个爆款商品,总量没超、热点已死。所以应用层限流还要有热点参数维度:以商品 ID 为 key 单独设阈值(比如单商品 200 QPS),爆款再热也不至于独占全站容量。Sentinel 的热点参数限流(Hot Param)就是干这个的,第 12 篇实战细讲;思想先立住:总量之外,永远给最热的那个维度单独立账本。
阈值是活的
最后一条纪律:三层阈值必须有动态调整能力——配置中心下发、控制台热更新(Sentinel 控制台即为此生),而不是写死在配置文件里重启生效。大促前手动收紧、扩容后放宽、发现异常流量时临时压制,都要求秒级生效。阈值是活的,防线才是活的。下一篇把前八篇的算法与分层做个总盘点:固定窗口、滑动窗口、漏桶、令牌桶,加上分布式与单机的组合,一张表选型定案。
评论 (0)