一、核心概念
1. 全局过滤器(GlobalFilter)
- 定义:对所有请求生效的过滤器,无论请求路由到哪个服务。
- 应用场景:
- 统一鉴权:校验 Token 或 Session。
- 日志记录:记录请求的耗时、IP、路径等。
- 限流:对高频接口进行流量控制。
- 参数校验:校验请求头或查询参数。
2. 局部过滤器(GatewayFilter)
- 定义:仅对特定路由生效的过滤器,用于细粒度控制。
- 应用场景:
- 路径重写:
RewritePath
过滤器修改请求路径。 - 负载均衡:结合
LoadBalancerClientFilter
实现服务发现。
- 路径重写:
3. 过滤器执行顺序
- 优先级规则:
- 前置阶段(pre):优先级高的过滤器先执行。
- 后置阶段(post):优先级高的过滤器后执行。
- 默认顺序:
GlobalFilter
的getOrder()
返回值越小,优先级越高。
二、操作步骤(详细版)
1. 引入依赖
在 pom.xml
中添加以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
2. 创建全局过滤器
(1)实现 GlobalFilter
接口
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 前置处理逻辑
System.out.println("请求开始: " + exchange.getRequest().getPath());
// 继续执行后续过滤器
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
// 后置处理逻辑(响应发送后执行)
System.out.println("请求结束");
}));
}
@Override
public int getOrder() {
return 0; // 数值越小优先级越高
}
}
(2)配置过滤器顺序
- 方式一:通过
@Order
注解@Component @Order(1) public class AuthFilter implements GlobalFilter, Ordered { ... }
- 方式二:在
application.yml
中配置spring: cloud: gateway: default-filters: - name: MyGlobalFilter args: order: 0
3. 测试全局过滤器
(1)启动网关服务
确保网关服务已启动,并配置了至少一个路由规则:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: http://localhost:8081
predicates:
- Path=/user/**
(2)发送请求
访问任意路由路径(如 http://localhost:8080/user/1
),观察控制台输出:
请求开始: /user/1
请求结束
4. 动态调整过滤器
(1)通过 Nacos 配置中心动态更新
- 添加 Nacos 依赖:
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>
- 在 Nacos 配置文件中定义过滤器规则:
spring: cloud: gateway: globalfilters: - name: MyGlobalFilter args: order: 0
三、常见错误及解决方案
1. 过滤器未生效
- 原因:
- 未正确实现
GlobalFilter
接口。 - 未通过
@Component
注解注册。
- 未正确实现
- 解决方案:
- 检查类是否实现
GlobalFilter
和Ordered
接口。 - 确保类被 Spring 扫描(如包路径一致)。
- 检查类是否实现
2. 过滤器顺序异常
- 原因:
getOrder()
返回值未正确设置。- 未区分
pre
和post
阶段。
- 解决方案:
- 通过
getOrder()
明确优先级。 - 使用
OrderedGatewayFilter
显式指定阶段。
- 通过
3. 阻塞线程导致性能下降
- 原因:
- 在
filter
方法中执行同步阻塞操作(如数据库查询)。
- 在
- 解决方案:
- 使用异步处理(如
Mono.fromRunnable()
)。 - 将耗时操作提交到线程池。
- 使用异步处理(如
四、注意事项
避免阻塞操作:
- 使用
WebFlux
的非阻塞模型,避免在filter
中直接调用thread.sleep()
。 - 耗时操作应异步化(如日志写入、外部 API 调用)。
- 使用
合理设置优先级:
- 鉴权过滤器应设置较高优先级(如
order=-1
),确保在路由前校验。 - 日志过滤器可设置较低优先级(如
order=1000
),在响应后记录。
- 鉴权过滤器应设置较高优先级(如
异常处理:
- 使用
Mono.error()
抛出异常,确保网关返回统一错误码。 - 避免直接抛出
RuntimeException
,防止异常未捕获。
- 使用
五、使用技巧
1. 日志记录优化
- 示例:记录请求耗时
public class LoggingFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { long startTime = System.currentTimeMillis(); exchange.getAttributes().put("startTime", startTime); return chain.filter(exchange).then(Mono.fromRunnable(() -> { long duration = System.currentTimeMillis() - startTime; System.out.println("请求耗时: " + duration + "ms"); })); } @Override public int getOrder() { return 0; } }
2. 参数传递与共享
- 示例:在过滤器间传递数据
exchange.getAttributes().put("userId", "123"); String userId = exchange.getAttribute("userId");
3. 条件判断过滤
- 示例:根据请求头动态跳过过滤
if (exchange.getRequest().getHeaders().containsKey("Skip-Auth")) { return chain.filter(exchange); }
六、最佳实践
1. 统一鉴权
- 场景:所有请求需携带 Token。
- 策略:
- 实现
AuthFilter
,校验请求头中的Authorization
字段。 - 若未通过校验,返回
401 Unauthorized
。
- 实现
2. 限流与熔断
- 场景:防止高频请求击穿后端服务。
- 策略:
- 结合 Sentinel 或 Resilience4j 实现限流。
- 在全局过滤器中调用限流规则。
3. 日志聚合与监控
- 场景:集中记录请求日志,便于排查问题。
- 策略:
- 使用
Logback
或ELK
实现日志收集。 - 记录关键字段(如
IP
、Path
、Status
)。
- 使用
七、性能优化
减少阻塞操作:
- 将数据库查询、外部 API 调用异步化。
- 使用
Reactor
的publishOn
指定线程池。
缓存频繁校验数据:
- 对 Token、用户权限等高频校验数据使用本地缓存(如 Caffeine)。
优化过滤器链:
- 合并多个过滤器逻辑,减少链路长度。
- 避免在过滤器中执行复杂计算。
动态规则管理:
- 通过 Nacos 或 Apollo 动态更新过滤器规则,无需重启服务。
八、总结
Spring Cloud Gateway 的全局过滤器是实现统一请求处理的核心工具。通过合理设计过滤器逻辑、优化执行顺序、避免阻塞操作,可以有效提升网关的稳定性和性能。实际开发中,建议结合业务需求选择合适的过滤器策略,并通过日志与监控持续优化过滤器链。