SpringNotes

第 19 章:网关

zjc 于 2026-01-19 发布

这是《Spring Boot 与 Spring Cloud 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 网关是外部流量进入内部系统的统一边界,负责路由、认证、限流、熔断、协议转换、观测和安全策略。它应该保持轻量稳定,避免承载业务逻辑。

19.1 网关职责

Client
  -> Gateway
     -> 路由
     -> 认证
     -> 限流
     -> 日志
     -> 负载均衡
     -> Order Service
职责 说明
路由 按路径、Host、Header 转发
认证 验证 Token、签名
授权 判断可访问资源
限流 保护后端
熔断 阻止故障扩散
观测 记录访问日志和指标
安全 TLS、WAF、CORS
发布 灰度、蓝绿、金丝雀

不建议在网关写业务规则,例如复杂促销计算。网关逻辑越重,变更和故障影响越大。

19.2 Spring Cloud Gateway

依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway-server-webflux</artifactId>
</dependency>

配置:

server:
  port: 8080

spring:
  cloud:
    gateway:
      server:
        webflux:
          routes:
            - id: order-route
              uri: lb://order-service
              predicates:
                - Path=/api/orders/**
              filters:
                - name: Retry
                  args:
                    retries: 2
                    statuses: BAD_GATEWAY
                - StripPrefix=0

Spring Cloud Gateway 基于 Reactive 技术栈,不适合直接使用阻塞 API。版本较新时配置命名可能有调整,以当前文档为准。

19.3 路由谓词

常用谓词:

谓词 说明
Path 路径匹配
Method HTTP 方法
Header 请求头
Query 查询参数
Host 域名
Weight 按权重路由
Cookie Cookie 匹配

示例:

routes:
  - id: canary
    uri: lb://order-service-v2
    predicates:
      - Path=/api/orders/**
      - Header=X-Canary, true

路由顺序要明确,避免宽泛规则先匹配。

19.4 过滤器

全局过滤器:

@Component
public class TraceIdFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String traceId = Optional.ofNullable(exchange.getRequest().getHeaders().getFirst("X-Trace-Id"))
                .orElseGet(() -> UUID.randomUUID().toString());

        exchange = exchange.mutate()
                .request(builder -> builder.header("X-Trace-Id", traceId))
                .build();

        exchange.getResponse().getHeaders().set("X-Trace-Id", traceId);
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -100;
    }
}

过滤器顺序:

TraceId
  -> 安全
  -> 限流
  -> 认证
  -> 路由修改
  -> 转发
  -> 响应处理

19.5 认证与授权

常见模式:

模式 做法
JWT 网关验签,传递用户声明
OAuth2 网关或资源服务器校验 token
Session 网关透传 Cookie
API Key 识别调用方
mTLS 服务间身份认证

认证后传递:

X-User-Id
X-User-Roles
X-Client-Id
X-Trace-Id

必须注意:

  1. 这些 Header 只能由网关注入或覆盖;
  2. 内部服务不能信任外部传入的伪造身份头;
  3. 敏感 token 不应原样写入日志;
  4. 授权规则要与资源绑定。

19.6 限流

限流维度:

  1. 全局;
  2. 服务;
  3. 路径;
  4. 用户;
  5. IP;
  6. 租户;
  7. API Key。

算法:

算法 特点
固定窗口 简单,边界突刺
滑动窗口 平滑,内存稍高
令牌桶 允许突发
漏桶 平滑输出
分布式 Redis + Lua 多实例一致

响应:

429 Too Many Requests
Retry-After: 1
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0

限流不是只给 429,还要考虑排队、优先级和降级。

19.7 超时与重试

配置:

spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 1000
        response-timeout: 5s

超时链路:

客户端超时
  >= 网关总超时
     > 后端服务超时

网关重试必须谨慎:

  1. 默认只重试幂等请求;
  2. POST 下单不应盲目重试;
  3. 有幂等键才可重试;
  4. 限制重试次数;
  5. 设置熔断保护。

19.8 灰度发布

常见策略:

策略 做法
Header 灰度 指定用户或内部流量
权重灰度 5% 流量到新版本
租户灰度 指定客户先体验
地域灰度 某机房先发布
Cookie 灰度 白名单用户

示例:

routes:
  - id: order-v1
    uri: lb://order-service-v1
    predicates:
      - Path=/api/orders/**
      - Weight=order-group, 95
  - id: order-v2
    uri: lb://order-service-v2
    predicates:
      - Path=/api/orders/**
      - Weight=order-group, 5

必须配套:

  1. 版本指标;
  2. 快速回滚;
  3. 一致性校验;
  4. 用户粘性;
  5. 业务观察窗口。

19.9 可观测性

访问日志字段:

time
remote_ip
method
path
status
bytes
request_time
upstream_service
upstream_host
upstream_status
trace_id
user_id
client_id

指标:

gateway_request_total
gateway_request_seconds
gateway_status_total
gateway_timeout_total
gateway_limit_total
gateway_upstream_seconds
gateway_active_connections

告警:

  1. 5xx 比例;
  2. P99 延迟;
  3. 429 增长;
  4. upstream timeout;
  5. 路由无健康实例;
  6. 网关内存和连接数。

19.10 高可用

部署:

DNS / SLB
  -> Gateway 多实例
     -> 服务多实例

要点:

  1. 网关无状态;
  2. 配置热更新可回滚;
  3. 后端健康检查;
  4. 网关 CPU 和内存充足;
  5. 避免阻塞调用;
  6. 限制请求体大小;
  7. 防慢连接攻击;
  8. TLS 证书管理;
  9. 压测长连接和并发;
  10. 定期故障演练。

本章小结

网关是流量、安全、观测和发布策略的统一边界。Spring Cloud Gateway 提供路由谓词和过滤器模型,生产中要重点治理认证头、超时、限流、重试、灰度和可观测性。网关应保持轻量、无状态和高可用,业务规则应下沉到服务内部。

思考题

  1. 为什么网关不适合承载复杂业务逻辑?
  2. 网关认证后如何安全传递用户身份?
  3. 限流维度如何选择?
  4. 哪些请求可以在网关重试?
  5. 灰度发布需要哪些配套能力?