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,POST | HTTP 方法 |
| 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/24 | IP 段匹配 |
| 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 Gateway | Zuul 1.x |
|---|
| IO 模型 | 非阻塞(WebFlux) | 阻塞(Servlet) |
| 性能 | 高 | 中 |
| 维护状态 | 活跃 | 停维护 |
| 限流 | 内置(Redis) | 需插件 |
相关链接
Spring Cloud
架构与设计
Redis 与分布式
数据库