Spring Cloud Gateway 核心
Spring Cloud Gateway 简介
Spring Cloud Gateway 是 Spring Cloud 官方推出的网关解决方案,基于 Spring WebFlux 构建,提供路由转发、过滤器、限流等功能。
核心概念
- 路由(Route):网关的基本构建块,由 ID、目标 URI、断言和过滤器组成
- 断言(Predicate):匹配 HTTP 请求的条件
- 过滤器(Filter):在请求前后执行逻辑
- 谓词工厂(Predicate Factory):创建断言的工厂
- 过滤器工厂(Filter Factory):创建过滤器的工厂
工作原理
┌─────────────┐
│ Client │
└──────┬──────┘
│
▼
┌─────────────────────────────────────────┐
│ Spring Cloud Gateway │
│ │
│ ┌─────────────────────────────────┐ │
│ │ Handler Mapping │ │
│ │ (Route Predicate Router) │ │
│ └──────────────┬──────────────────┘ │
│ │ │
│ ┌──────────────▼──────────────────┐ │
│ │ Web Filter Chain │ │
│ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Filter │ │ Filter │ ... │ │
│ │ │ Pre │ │ Post │ │ │
│ │ └─────────┘ └─────────┘ │ │
│ └──────────────┬──────────────────┘ │
│ │ │
│ ┌──────────────▼──────────────────┐ │
│ │ Proxy Handler │ │
│ └──────────────┬──────────────────┘ │
└─────────────────┼───────────────────────┘
│
▼
┌────────────────┐
│ Microservices │
└────────────────┘
核心优势
- 性能优异:基于 WebFlux 和 Netty,异步非阻塞
- 灵活路由:支持多种断言规则
- 丰富过滤器:内置多种过滤器,支持自定义扩展
- 集成性好:与 Spring Cloud 生态无缝集成
- 可观测性:支持指标收集和链路追踪
快速开始
1. 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2. 配置路由
spring:
cloud:
gateway:
discovery:
locator:
enabled: true # 启用服务发现
lower-case-service-id: true # 服务名转小写
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
- AddRequestHeader=X-Request-Source, gateway
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
filters:
- StripPrefix=1
3. 启动类
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
路由配置
断言工厂
1. Path 断言
predicates:
- Path=/api/users/**
- Path=/api/orders/{id}
2. Method 断言
predicates:
- Method=GET,POST
3. Header 断言
predicates:
- Header=X-Request-Id, \d+
4. Query 断言
predicates:
- Query=page, \d+
- Query=keyword, .+
5. Cookie 断言
predicates:
- Cookie=sessionId, .+
6. Host 断言
predicates:
- Host=**.example.com
7. Between 断言
predicates:
- Between=2026-01-01T00:00:00.000Z[Asia/Shanghai], 2026-12-31T23:59:59.999Z[Asia/Shanghai]
8. Before/After 断言
predicates:
- Before=2026-06-01T00:00:00.000Z[Asia/Shanghai]
- After=2026-01-01T00:00:00.000Z[Asia/Shanghai]
9. Weight 断言(权重)
predicates:
- Weight=group1, 80 # 80% 流量
组合断言
predicates:
- Path=/api/users/**
- Method=GET,POST
- Header=X-Request-Id, \d+
过滤器
内置过滤器
1. StripPrefix
filters:
- StripPrefix=1 # 去掉路径的第一部分
2. AddRequestHeader
filters:
- AddRequestHeader=X-Request-Source, gateway
3. AddResponseHeader
filters:
- AddResponseHeader=X-Response-Time, 2026-04-10
4. SetRequestHeader
filters:
- SetRequestHeader=Host, new-host
5. RemoveRequestHeader
filters:
- RemoveRequestHeader=Cookie
6. RewritePath
filters:
- RewritePath=/api/(?<segment>.*), /$\{segment}
7. RedirectTo
filters:
- RedirectTo=302, http://example.com
8. CircuitBreaker
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/fallback
9. RequestRateLimiter
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
自定义过滤器
全局过滤器
@Component
public class GlobalAuthFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
// 获取认证信息
String token = request.getHeaders().getFirst("Authorization");
// 验证 Token
if (!validateToken(token)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 添加用户信息到请求头
ServerHttpRequest mutatedRequest = request.mutate()
.header("X-User-ID", getUserIdFromToken(token))
.build();
return chain.filter(exchange.mutate().request(mutatedRequest).build());
}
@Override
public int getOrder() {
return -100; // 优先级
}
private boolean validateToken(String token) {
// Token 验证逻辑
return token != null && token.startsWith("Bearer ");
}
private String getUserIdFromToken(String token) {
// 从 Token 中提取用户 ID
return "user123";
}
}
局部过滤器工厂
@Component
public class CustomFilterFactory extends AbstractGatewayFilterFactory<CustomFilterFactory.Config> {
public CustomFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
// 前置处理
log.info("执行自定义过滤器:{}", config.getName());
return chain.filter(exchange)
.then(Mono.fromRunnable(() -> {
// 后置处理
log.info("响应状态码:{}", exchange.getResponse().getStatusCode());
}));
};
}
public static class Config {
private String name;
// getter/setter
}
}
使用:
filters:
- CustomFilter=name
负载均衡
集成 Spring Cloud LoadBalancer
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
httpclient:
pool:
type: ELASTIC
max-connections: 100
max-connections-per-route: 20
负载均衡策略
@Configuration
public class LoadBalancerConfig {
@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
@Bean
public ReactorLoadBalancer<ServiceInstance> loadBalancer(
Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory
) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return loadBalancerClientFactory.getInstance(name);
}
}
跨域配置
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsWebFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOriginPattern("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
config.setAllowCredentials(true);
config.setMaxAge(3600L);
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}
监控与指标
集成 Actuator
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
management:
endpoints:
web:
exposure:
include: health,info,metrics,gateway
endpoint:
gateway:
enabled: true
访问指标
# 查看路由信息
curl http://localhost:8080/actuator/gateway/routes
# 查看全局指标
curl http://localhost:8080/actuator/metrics/gateway.requests
# 查看健康状态
curl http://localhost:8080/actuator/health
高可用部署
1. 多实例部署
server:
port: 8080 # 不同实例使用不同端口
2. Nginx 负载均衡
upstream gateway {
server gateway1:8080;
server gateway2:8080;
server gateway3:8080;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://gateway;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
3. 配置持久化
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
metadata:
version: 1.0.0
生产实践
1. 统一鉴权
@Component
public class AuthFilter implements GlobalFilter {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
// 白名单放行
if (isWhiteList(request.getPath().value())) {
return chain.filter(exchange);
}
// 验证 Token
String token = extractToken(request);
if (!validateToken(token)) {
return unauthorized(exchange);
}
// 传递用户信息
return chain.filter(exchange);
}
private boolean isWhiteList(String path) {
return path.startsWith("/api/auth/");
}
private String extractToken(ServerHttpRequest request) {
String bearerToken = request.getHeaders().getFirst("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return null;
}
private boolean validateToken(String token) {
return redisTemplate.hasKey("token:" + token);
}
private Mono<Void> unauthorized(ServerWebExchange exchange) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
}
2. 限流配置
@Configuration
public class RateLimiterConfig {
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
@Bean
public KeyResolver userKeyResolver() {
return exchange -> {
String userId = exchange.getRequest().getHeaders().getFirst("X-User-ID");
return Mono.just(userId != null ? userId : "anonymous");
};
}
}
3. 日志记录
logging:
level:
org.springframework.cloud.gateway: DEBUG
reactor.netty.http.client: DEBUG
常见问题
1. 路由不生效
问题:配置的路由没有生效
排查步骤:
- 检查路由 ID 是否唯一
- 检查断言配置
- 查看网关日志
2. 跨域问题
问题:前端调用报跨域错误
解决方案:
- 配置 CorsWebFilter
- 检查 CORS 配置
3. 文件上传失败
问题:大文件上传失败
解决方案:
spring:
cloud:
gateway:
httpclient:
max-in-memory-size: 104857600 # 100MB
总结
Spring Cloud Gateway 提供了强大的路由和过滤功能,是微服务架构的理想网关选择。
通过合理配置路由规则和过滤器,可以实现统一鉴权、限流、日志记录等功能。
在生产环境中,建议配置多实例实现高可用,并完善监控和日志记录。