Spring Cloud Gateway 路由、过滤器与限流机制详解
Spring Cloud Gateway 基于 WebFlux 响应式模型实现高性能 API 网关。文章解析其核心架构、路由匹配机制、过滤器链执行顺序及自定义开发方法。重点介绍分布式限流(令牌桶算法)与熔断降级策略,并结合电商场景提供完整配置示例、性能优化方案及生产环境故障排查指南。涵盖静态/动态路由、服务发现集成及安全认证过滤器的企业级实践。

Spring Cloud Gateway 基于 WebFlux 响应式模型实现高性能 API 网关。文章解析其核心架构、路由匹配机制、过滤器链执行顺序及自定义开发方法。重点介绍分布式限流(令牌桶算法)与熔断降级策略,并结合电商场景提供完整配置示例、性能优化方案及生产环境故障排查指南。涵盖静态/动态路由、服务发现集成及安全认证过滤器的企业级实践。

在微服务化项目中,常因缺乏统一 API 网关导致代码重复且难以维护。客户端需要知道每个服务的具体地址,一旦服务地址变更,所有客户端都需要更新。
API 网关的核心价值在于它作为系统的唯一入口,统一处理所有客户端请求,实现了关注点分离。
与 Nginx、Zuul 等传统方案相比,Spring Cloud Gateway 具有明显优势:
| 特性 | Nginx | Zuul 1.x | Spring Cloud Gateway |
|---|---|---|---|
| 编程模型 | 同步阻塞 | 同步阻塞 | 异步非阻塞 |
| 性能 | 高 | 低 | 高 |
| 可扩展性 | 中等 | 高 | 高 |
| Spring 生态集成 | 弱 | 强 | 原生支持 |
| 配置方式 | 文件配置 | 注解/配置 | 声明式配置 |
性能测试数据(每秒请求数,100 并发连接):
虽然绝对性能略低于 Nginx,但 Spring Cloud Gateway 提供了更好的编程灵活性和 Spring 生态集成能力。
Spring Cloud Gateway 采用分层架构设计,核心组件协同工作:
核心组件说明:
RoutePredicateHandlerMapping:路由匹配,决定请求应该由哪个路由处理FilteringWebHandler:执行过滤器链,包括全局过滤器和路由过滤器NettyRoutingFilter:实际转发请求到后端服务ServerWebExchange:封装请求和响应上下文的核心对象Spring Cloud Gateway 基于 Project Reactor 实现响应式编程,这是其高性能的关键:
// Reactor 编程模型示例
public class GatewayReactiveExample {
public Mono<Void> handleRequest(ServerWebExchange exchange) {
return Mono.fromRunnable(() -> {
// 异步处理请求
log.info("处理请求:{}", exchange.getRequest().getPath());
})
.subscribeOn(Schedulers.boundedElastic()) // 指定调度器
.then(chain.filter(exchange))
.doOnSuccess(v -> log.info("请求处理成功"))
.doOnError(e -> log.error("请求处理失败", e));
}
// 背压支持示例
public Flux<DataBuffer> handleStreamingRequest(ServerWebExchange exchange) {
return exchange.getRequest().getBody()
.map(dataBuffer -> {
// 处理数据流,支持背压
return processDataBuffer(dataBuffer);
})
.take(1000) // 限制处理数量
.timeout(Duration.ofSeconds(30)); // 超时控制
}
}
静态路由适用于环境固定的场景,配置简单直观:
spring:
cloud:
gateway:
routes:
- id: user_service_route
uri: http://localhost:8081
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
- AddRequestHeader=X-Gateway-Request, true
- id: order_service_route
uri: http://localhost:8082
predicates:
- Path=/api/orders/**
- Method=GET,POST
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
key-resolver: "#{@userKeyResolver}"
路由配置关键元素:
id:路由唯一标识,便于管理和监控uri:目标服务地址,支持 lb:// 服务发现集成predicates:路由匹配条件,支持路径、方法、Header 等filters:请求处理过滤器链生产环境中,动态路由是必备能力。推荐基于数据库的动态路由方案:
// 动态路由配置实体
@Entity
@Table(name = "gateway_routes")
public class GatewayRouteEntity {
@Id
private String id;
private String uri;
@Column(columnDefinition = "TEXT")
private String predicates; // JSON 格式存储断言配置
@Column(columnDefinition = "TEXT")
private String filters; // JSON 格式存储过滤器配置
private Integer routeOrder;
private Boolean enabled;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
// 动态路由仓库实现
@Component
public class DatabaseRouteDefinitionRepository implements RouteDefinitionRepository {
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
@Autowired
private GatewayRouteService routeService;
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
return Flux.fromIterable(routeService.findAllEnabledRoutes())
.map(this::convertToRouteDefinition);
}
// 动态添加路由
@EventListener
public void handleRouteAdd(RouteAddEvent event) {
RouteDefinition routeDefinition = event.getRouteDefinition();
routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
applicationContext.publishEvent( ());
}
{
routeDefinitionWriter.delete(Mono.just(event.getRouteId())).subscribe();
applicationContext.publishEvent( ());
}
}
Spring Cloud Gateway 与 Nacos、Eureka 等服务发现组件无缝集成:
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:
- RewritePath=/api/users/(?<segment>.*), /${segment}
- id: order_service
uri: lb://order-service
predicates:
- Path=/api/orders/**
- Header=X-Requested-With, XMLHttpRequest
这种配置下,网关会自动从注册中心获取服务实例列表,并实现负载均衡。
Spring Cloud Gateway 的过滤器分为两大类,执行顺序由 Ordered 接口控制:
过滤器执行顺序示例:
// 自定义全局过滤器
@Component
public class AuthFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (!validateToken(token)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -100; // 高优先级,最先执行
}
}
// 日志记录过滤器
@Component
public class LoggingFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
long startTime = System.currentTimeMillis();
return chain.filter(exchange).doOnSuccessOrError((v, e) -> {
long duration = System.currentTimeMillis() - startTime;
log.info("请求路径:{}, 耗时:{}ms, 状态:{}", exchange.getRequest().getPath(), duration, exchange.getResponse().getStatusCode());
});
}
{
;
}
}
Spring Cloud Gateway 提供了丰富的内置过滤器:
spring:
cloud:
gateway:
routes:
- id: enhanced_route
uri: lb://backend-service
predicates:
- Path=/api/**
filters:
# 1. 路径重写
- RewritePath=/api/(?<segment>.*), /${segment}
# 2. 请求头处理
- AddRequestHeader=X-Request-Gateway, true
- RemoveRequestHeader=Secret-Header
- SetRequestHeader=X-User-ID, 12345
# 3. 响应头处理
- AddResponseHeader=X-Response-Gateway, processed
- SetResponseHeader=X-Cache-Hit, false
# 4. 重试机制
- name: Retry
args:
retries: 3
methods: GET,POST
statuses: BAD_GATEWAY,SERVICE_UNAVAILABLE
backoff:
firstBackoff: 10ms
maxBackoff: 100ms
factor:
实际项目中,经常需要开发自定义过滤器满足特定业务需求:
// 自定义网关过滤器工厂
@Component
public class RateLimitByUserGatewayFilterFactory extends AbstractGatewayFilterFactory<RateLimitByUserGatewayFilterFactory.Config> {
@Autowired
private RedisTemplate<String, Integer> redisTemplate;
public RateLimitByUserGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
String userId = getUserId(exchange);
String key = "rate_limit:" + config.getType() + ":" + userId;
// 使用 Redis 实现滑动窗口限流
Long current = redisTemplate.opsForValue().increment(key, 1);
if (current == 1) {
redisTemplate.expire(key, config.getWindowSeconds(), TimeUnit.SECONDS);
}
if (current > config.getMaxRequests()) {
exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUISITIONS);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
};
}
// 配置类
public static class Config {
private String type; // 限流类型
maxRequests;
windowSeconds;
}
}
RouteLocator {
builder.routes()
.route(, r -> r.path()
.filters(f -> f.filter( ()
.apply( (, , ))))
.uri())
.build();
}
在高并发场景下,分布式限流是保护后端服务的关键技术:
spring:
cloud:
gateway:
routes:
- id: limited_route
uri: lb://backend-service
predicates:
- Path=/api/**
filters:
- name: RequestRateLimiter
args:
# 使用 Redis 实现分布式限流
redis-rate-limiter.replenishRate: 100 # 每秒生成 100 个令牌
redis-rate-limiter.burstCapacity: 200 # 令牌桶容量 200
redis-rate-limiter.requestedTokens: 1 # 每个请求消耗 1 个令牌
key-resolver: "#{@apiKeyResolver}" # 限流键解析器
限流键解析器实现:
@Configuration
public class RateLimitConfig {
// 按用户限流
@Bean
public KeyResolver userKeyResolver() {
return exchange -> {
String userId = exchange.getRequest().getHeaders().getFirst("X-User-ID");
if (StringUtils.isEmpty(userId)) {
// 从 JWT token 中解析用户 ID
String token = extractToken(exchange);
userId = jwtHelper.getUserIdFromToken(token);
}
return Mono.just(StringUtils.isEmpty(userId) ? "anonymous" : userId);
};
}
// 按 IP 限流
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> {
String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
return Mono.just(ip);
};
}
// 按 API 路径限流
@Bean
public KeyResolver apiKeyResolver() {
return exchange -> {
String path = exchange.getRequest().getPath().value();
String method = exchange.getRequest().getMethodValue();
return Mono.just(method + ":" + path);
};
}
}
Spring Cloud Gateway 基于令牌桶算法实现限流,其核心原理如下:
算法实现代码:
public class TokenBucketRateLimiter {
private final int capacity; // 桶容量
private final double refillRate; // 令牌补充速率
private double tokens; // 当前令牌数
private long lastRefillTimestamp; // 最后补充时间
public synchronized boolean tryAcquire(int tokensRequested) {
// 1. 补充令牌
refillTokens();
// 2. 检查是否有足够令牌
if (tokens >= tokensRequested) {
tokens -= tokensRequested;
return true;
}
return false;
}
private void refillTokens() {
long now = System.currentTimeMillis();
if (now > lastRefillTimestamp) {
double secondsSinceLastRefill = (now - lastRefillTimestamp) / 1000.0;
double tokensToAdd = secondsSinceLastRefill * refillRate;
tokens = Math.min(capacity, tokens + tokensToAdd);
lastRefillTimestamp = now;
}
}
}
// Redis 分布式限流 Lua 脚本
public class {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
;
}
当后端服务不可用时,熔断机制可以防止故障扩散:
@Configuration
public class CircuitBreakerConfig {
@Bean
public Customizer<ReactiveResilience4JCircuitBreakerFactory> defaultConfig() {
return factory -> {
factory.configureDefault(id -> new CircuitBreakerConfig.Builder()
.slidingWindowType(SlidingWindowType.TIME_BASED)
.slidingWindowSize(100) // 滑动窗口大小
.minimumNumberOfCalls(10) // 最小调用次数
.failureRateThreshold(50) // 失败率阈值
.waitDurationInOpenState(Duration.ofSeconds(60)) // 开启状态等待时间
.permittedNumberOfCallsInHalfOpenState(10) // 半开状态允许调用次数
.recordExceptions(IOException.class, TimeoutException.class)
.build());
};
}
}
// 使用熔断器的路由配置
@Bean
public RouteLocator circuitBreakerRoute(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuit_breaker_route", r -> r.path("/api/unstable/**")
.filters(f -> f.circuitBreaker(config -> config
.setName("backendBreaker")
.setFallbackUri("forward:/fallback/unavailable")))
.uri("lb://unstable-service"))
.build();
}
// 降级处理控制器
@RestController
public class FallbackController {
@GetMapping("/fallback/unavailable")
public Mono<ResponseEntity<Map<String, Object>>> serviceUnavailable() {
Mono.just(ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
.body(Map.of(
, ,
, ,
, System.currentTimeMillis()
)));
}
}
基于真实电商场景,设计完整的网关方案。
spring:
cloud:
gateway:
httpclient:
connect-timeout: 5000
response-timeout: 30s
pool:
max-connections: 1000
acquire-timeout: 5000
routes:
# 用户服务路由
- id: user_service_v1
uri: lb://user-service
predicates:
- Path=/api/v1/users/**
- Header=X-API-Version, v1
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 50
redis-rate-limiter.burstCapacity: 100
key-resolver: "#{@userKeyResolver}"
- CacheRequestBody
- name: CircuitBreaker
args:
name: userServiceBreaker
fallbackUri: forward:/fallback/userUnavailable
# 商品服务路由
电商系统必须重视安全防护:
@Component
public class SecurityFilter implements GlobalFilter, Ordered {
@Autowired
private JwtHelper jwtHelper;
@Autowired
private BlacklistService blacklistService;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1. IP 黑名单检查
String clientIp = getClientIp(exchange);
if (blacklistService.isIpBlocked(clientIp)) {
return unauthorizedResponse(exchange, "IP 地址被限制访问");
}
// 2. 路径白名单检查
if (isExcludedPath(exchange.getRequest().getPath().value())) {
return chain.filter(exchange);
}
// 3. JWT 令牌验证
String token = extractToken(exchange);
if (!jwtHelper.validateToken(token)) {
return unauthorizedResponse(exchange, "令牌无效或已过期");
}
// 4. 权限验证
String path = exchange.getRequest().getPath().value();
String method = exchange.getRequest().getMethodValue();
if (!hasPermission(token, path, method)) {
return forbiddenResponse(exchange, "权限不足");
}
// 5. 添加用户信息到 Header
String jwtHelper.getUserIdFromToken(token);
exchange = exchange.mutate()
.request(builder -> builder.header(, userId))
.build();
chain.filter(exchange);
}
{
HIGHEST_PRECEDENCE;
}
{
path.startsWith() || path.equals() || path.startsWith();
}
}
基于实际压测数据,提供性能优化建议:
线程模型优化:
# 优化 Netty 线程模型
server:
netty:
connection-timeout: 5000
idle-timeout: 60s
reactor:
netty:
# EventLoop 线程数 = CPU 核心数 * 2
io-worker-count: 16
# 内存分配优化
allocator:
max-order: 3
chunk-size: 16MB
spring:
cloud:
gateway:
httpclient:
# 连接池配置
pool:
type: elastic
max-connections: 1000
acquire-timeout: 5000
max-idle-time: 60s
JVM 参数优化:
# 网关服务 JVM 优化参数
-Xms2g -Xmx2g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1ReservePercent=25
-XX:InitiatingHeapOccupancyPercent=30
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/logs/gateway/heapdump.hprof
完善的监控是生产环境必备能力:
# Micrometer 监控配置
management:
metrics:
export:
prometheus:
enabled: true
datadog:
enabled: false
web:
server:
request:
autotime:
enabled: true
distribution:
percentiles-histogram:
http.server.requests: true
endpoint:
metrics:
enabled: true
prometheus:
enabled: true
tracing:
sampling:
probability: 0.1 # 采样率 10%
关键监控指标:
gateway.requests.totalgateway.requests.durationgateway.requests.limitedgateway.errors.total问题 1:路由不生效
// 路由调试端点
@RestController
@RequestMapping("/gateway/debug")
public class GatewayDebugController {
@Autowired
private RouteLocator routeLocator;
@GetMapping("/routes")
public Flux<Route> listRoutes() {
return routeLocator.getRoutes()
.doOnNext(route -> {
log.info("路由 ID: {}, URI: {}, 顺序:{}", route.getId(), route.getUri(), route.getOrder());
});
}
@GetMapping("/match")
public Mono<Route> matchRoute(@RequestParam String path) {
return routeLocator.getRoutes()
.filter(route -> {
// 模拟请求匹配逻辑
ServerWebExchange exchange = createMockExchange(path);
return route.getPredicate().test(exchange);
})
.next();
}
}
问题 2:内存泄漏排查
@Component
public class MemoryMonitor {
@Scheduled(fixedRate = 60000) // 每分钟检查一次
public void monitorMemory() {
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();
double heapUsedPercent = (double) heapUsage.getUsed() / heapUsage.getMax() * 100;
double nonHeapUsedPercent = (double) nonHeapUsage.getUsed() / nonHeapUsage.getMax() * 100;
if (heapUsedPercent > 80) {
log.warn("堆内存使用率过高:{}%", String.format("%.2f", heapUsedPercent));
// 触发 GC 并记录内存快照
System.gc();
}
if (nonHeapUsedPercent > 90) {
log.error("非堆内存使用率过高:{}%", String.format("%.2f", nonHeapUsedPercent));
// 告警并记录线程栈
dumpThreadStacks();
}
}
}
根据项目规模和技术栈选择合适的网关方案:
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| Spring Cloud 技术栈 | Spring Cloud Gateway | 生态集成度高,编程模型一致 |
| 高性能要求 | Nginx + OpenResty | 纯 C 开发,性能极致 |
| 多语言技术栈 | Kong/APISIX | Lua 插件生态丰富 |
| Service Mesh 集成 | Istio Gateway | 与服务网格深度集成 |

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online