连载中 7/20

网关层限流:Nginx 与 Spring Cloud Gateway

2026-07-09 · 1423 阅读 · 0 评论 · 0 赞

闸门装在入口

分布式限流解决了「总量怎么算准」,还有一个问题悬着:闸门装在哪一层最划算。答案从最外层说起——被拒绝的请求越早死,浪费越少:在网关被拒,只花了一次网关转发的资源;漏进应用层再拒,线程、连接池、序列化全白花了。所以网关层限流是性价比最高的一道闸,本篇看两位入口常客怎么装闸。

Nginx limit_req:漏桶的教科书实现

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

location /api/ {
    limit_req zone=api burst=20 nodelay;
    limit_req_status 429;
}

三行配置三个关键参数。rate=10r/s:恒定放行速率,每秒 10 个——这就是第 4 篇漏桶的「桶底小孔」。burst=20:桶容量 20,允许排队(或暂存)20 个超额请求,突发不至于被一刀切。nodelay:突发额度内的请求不排队、立即放行,超出的直接拒绝——不加 nodelay 是纯漏桶(排队匀速放),加了是「带突发宽容的漏桶」,接近令牌桶的手感。limit_req_zone 的 $binary_remote_addr 是按 IP 维度分桶(二进制存储省内存),10m 的共享内存能存十几万个 IP 状态。另有 limit_conn 管并发连接数,与 limit_req 管速率互补。

Spring Cloud Gateway:令牌桶进网关

微服务体系里网关常是 Spring Cloud Gateway,限流过滤器直接内置 Redis 令牌桶(第 6 篇 Lua 的官方封装版):

spring:
  cloud:
    gateway:
      routes:
        - id: order-route
          uri: lb://order-service
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 200    # 每秒发牌 200
                redis-rate-limiter.burstCapacity: 400    # 桶容量 400
                key-resolver: "#{@userKeyResolver}"      # 按什么维度分桶
@Bean
public KeyResolver userKeyResolver() {
    return exchange -> Mono.just(
        exchange.getRequest().getHeaders().getFirst("X-User-Id"));  // 按用户
}

replenishRate 是发牌速率,burstCapacity 是桶容量——令牌桶的两个旋钮原样暴露。真正的灵活性在 KeyResolver:按用户 ID、按 IP、按接口路径、按 Header 里的租户标识,分桶维度随业务定义,Redis 里每个 key 一个独立的桶。

网关的边界:看不见业务上下文

网关限流的盲区也在 KeyResolver 够不到的地方:「黄金会员每秒 10 单、普通会员 1 单」「下单要同时校验商品维度库存」——这些规则需要解析请求体、查会员等级,网关做业务解析既慢又危险(网关是全局咽喉,挂不得)。所以分工要清楚:网关卡粗的(IP 防刷、路由级总量、明显的恶意流量),应用层管细的(业务维度、方法级配额、精确到参数的规则)。网关层还有一个纪律:限流组件自身不能是单点——Redis 挂了网关限流失效,要有 fail-open 或本地兜底(第 6 篇的策略原样适用)。

不止一层闸

Nginx 或 SCG 的网关限流只是最外圈。老王的系统里,同样的流量从外到内要过三道闸:网关层挡 IP 防刷与路由总量;应用层用注解切面管业务维度配额(第 5 篇);数据层——连接池上限、慢查询超时,是最后的物理防线。三层阈值逐层收紧还是逐层放宽?下一篇把多级限流的设计讲透:怎么分配额度、怎么避免内层闸白装、怎么让三层打配合。

503

10 年全栈工程师 · 503咖啡馆主理人

#网关限流#Nginx#limit_req#Spring Cloud Gateway#令牌桶#KeyResolver

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞