API 网关

返回 Spring Cloud

Spring Cloud Gateway 是 Spring Cloud 官方的 API 网关,基于 Spring WebFlux + Reactor Netty(非阻塞),替代已停维护的 Zuul,提供路由、过滤、限流、熔断等能力。

核心概念

概念说明
Route(路由)网关基本单元,由 ID、目标 URI、Predicate、Filter 组成
Predicate(断言)匹配请求条件(路径、Header、Method、时间等)
Filter(过滤器)对请求/响应进行处理(鉴权、限流、改写 Header 等)

请求流程

Client
  │
  ▼
Gateway Handler Mapping(匹配 Route)
  │
  ▼
Gateway Web Handler
  │  Pre Filters
  ▼
Proxied Service(下游服务)
  │  Post Filters
  ▼
Client Response

依赖

<!-- 注意:Gateway 基于 WebFlux,不能同时引入 spring-boot-starter-web -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

路由配置

YAML 配置

spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service        # lb:// 从注册中心负载均衡
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1              # 去掉路径第一段 /api
            - AddRequestHeader=X-Gateway, true
 
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
            - Header=X-Version, v2
          filters:
            - RewritePath=/api/(?<segment>.*), /${segment}

Java 代码配置

@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("order-service", r -> r
            .path("/api/orders/**")
            .filters(f -> f
                .stripPrefix(1)
                .addRequestHeader("X-Gateway", "true")
                .circuitBreaker(c -> c
                    .setName("orderCB")
                    .setFallbackUri("forward:/fallback")))
            .uri("lb://order-service"))
        .build();
}

常用 Predicate 工厂

Predicate示例说明
Path- Path=/api/**路径匹配
Method- Method=GET,POSTHTTP 方法
Header- Header=X-Token, \d+Header 正则匹配
Query- Query=type, order请求参数匹配
After- After=2024-01-01T00:00:00+08:00时间匹配
RemoteAddr- RemoteAddr=192.168.0.0/24IP 段匹配
Weight- Weight=group1, 90权重路由(灰度)

常用 Filter 工厂

Filter说明
StripPrefix=N去掉路径前 N 段
RewritePath正则重写路径
AddRequestHeader添加请求 Header
AddResponseHeader添加响应 Header
RequestRateLimiter令牌桶限流(需 Redis)
CircuitBreaker集成 Resilience4j 熔断
Retry失败重试
SecureHeaders添加安全响应 Header

全局过滤器(鉴权示例)

@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
 
    @Override
    public Mono<Void> filter(ServerWebExchange exchange,
                              GatewayFilterChain chain) {
        String token = exchange.getRequest()
            .getHeaders().getFirst("Authorization");
 
        if (token == null || !isValid(token)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }
 
    @Override
    public int getOrder() { return -100; }
}

限流(Redis 令牌桶)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100
                redis-rate-limiter.burstCapacity: 200
                redis-rate-limiter.requestedTokens: 1
                key-resolver: "#{@ipKeyResolver}"
@Bean
public KeyResolver ipKeyResolver() {
    return exchange -> Mono.just(
        exchange.getRequest().getRemoteAddress()
            .getAddress().getHostAddress());
}

熔断降级

filters:
  - name: CircuitBreaker
    args:
      name: orderCircuitBreaker
      fallbackUri: forward:/fallback/order
@RestController
public class FallbackController {
    @GetMapping("/fallback/order")
    public Mono<Map<String, String>> orderFallback() {
        return Mono.just(Map.of("code", "503", "msg", "订单服务暂不可用"));
    }
}

跨域配置

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            allowed-origins: "https://example.com"
            allowed-methods: "*"
            allowed-headers: "*"
            allow-credentials: true
            max-age: 3600

与 Zuul 对比

特性Spring Cloud GatewayZuul 1.x
IO 模型非阻塞(WebFlux)阻塞(Servlet)
性能
维护状态活跃停维护
限流内置(Redis)需插件

相关链接

Spring Cloud

架构与设计

Redis 与分布式

数据库