SpringCloudGateway路由断言过滤

wen java案例 2

Spring Cloud Gateway 路由断言与过滤详解

核心概念

Spring Cloud Gateway 是基于Spring WebFlux的API网关,核心组件包括:

SpringCloudGateway路由断言过滤

组件 作用 类比
Route(路由) 网关的基本构建块 快递路线
Predicate(断言) 匹配HTTP请求的条件 快递筛选规则
Filter(过滤器) 对请求/响应进行修改 快递处理工序

路由配置方式

YAML配置方式

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Request-User, gateway

Java DSL配置方式

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("user-service", r -> r
            .path("/api/user/**")
            .filters(f -> f
                .stripPrefix(1)
                .addRequestHeader("X-Request-User", "gateway")
            )
            .uri("lb://user-service")
        )
        .build();
}

路由断言(Predicate)详解

时间相关断言

predicates:
  # 在指定时间之后
  - After=2024-01-01T00:00:00+08:00[Asia/Shanghai]
  # 在指定时间之前
  - Before=2025-01-01T00:00:00+08:00[Asia/Shanghai]
  # 在两个时间之间
  - Between=2024-06-01T00:00:00+08:00[Asia/Shanghai], 2024-12-31T23:59:59+08:00[Asia/Shanghai]

请求相关断言

predicates:
  # 路径匹配(支持Ant风格)
  - Path=/api/user/**, /api/order/**
  # 请求方法匹配
  - Method=GET,POST
  # 请求头匹配
  - Header=X-Request-Id, \d+    # 正则匹配
  - Header=X-Request-Type, proxy   # 精确匹配
  # 请求参数匹配
  - Query=userId, \d+           # 参数名+正则
  - Query=name                  # 仅检查参数存在
  # Cookie匹配
  - Cookie=sessionId, [a-z0-9]+
  # 请求体匹配
  - ReadBodyPredicateFactory.class

远程地址断言

predicates:
  # 来源IP匹配(支持CIDR)
  - RemoteAddr=192.168.1.1/24, 10.0.0.0/8
  # 来源主机名匹配
  - Host=**.example.com, *.test.com

权重路由断言

routes:
  - id: user-service-v1
    uri: http://localhost:8081
    predicates:
      - Path=/api/user/**
      - Weight=user-service, 80
  - id: user-service-v2
    uri: http://localhost:8082
    predicates:
      - Path=/api/user/**
      - Weight=user-service, 20

自定义断言

@Component
public class CustomPredicateFactory 
    extends AbstractRoutePredicateFactory<CustomPredicateFactory.Config> {
    public CustomPredicateFactory() {
        super(Config.class);
    }
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return exchange -> {
            // 自定义匹配逻辑
            String header = exchange.getRequest().getHeaders()
                .getFirst(config.getHeaderName());
            return config.getExpectedValue().equals(header);
        };
    }
    @Validated
    public static class Config {
        private String headerName;
        private String expectedValue;
        // getter/setter
    }
}

过滤器(Filter)详解

内置过滤器分类

类别 过滤器 说明
请求头 AddRequestHeader 添加请求头
RemoveRequestHeader 移除请求头
SetRequestHeader 设置请求头
响应头 AddResponseHeader 添加响应头
RemoveResponseHeader 移除响应头
SetResponseHeader 设置响应头
路径 StripPrefix 去除路径前缀
PrefixPath 添加路径前缀
RewritePath 重写路径
参数 AddRequestParameter 添加请求参数
RemoveRequestParameter 移除请求参数
重试 Retry 请求重试
限流 RequestRateLimiter 请求限流
熔断 CircuitBreaker 熔断器
其他 RedirectTo 重定向
SetStatus 设置HTTP状态码
DedupeResponseHeader 响应头去重
ModifyRequestBody 修改请求体
ModifyResponseBody 修改响应体

常用过滤器示例

请求/响应头操作

filters:
  - AddRequestHeader=X-Gateway,true
  - AddRequestHeader=X-Request-ID, ${uuid}
  - RemoveRequestHeader=Cookie
  - SetResponseHeader=X-Response-Time, ${current.time}
  - AddResponseHeader=X-Powered-By, Spring Gateway

路径操作

# 请求: /api/user/123
# 配置: StripPrefix=2
# 转发: /123
filters:
  - StripPrefix=2
# 请求: /user/123  
# 配置: PrefixPath=/api
# 转发: /api/user/123
filters:
  - PrefixPath=/api
# 使用正则重写
filters:
  - RewritePath=/api/user/(?<segment>.*), /$\{segment}

重试机制

filters:
  - name: Retry
    args:
      retries: 3
      statuses: BAD_GATEWAY, SERVICE_UNAVAILABLE
      methods: GET, POST
      series: SERVER_ERROR

限流

filters:
  - name: RequestRateLimiter
    args:
      redis-rate-limiter.replenishRate: 10
      redis-rate-limiter.burstCapacity: 20
      redis-rate-limiter.requestedTokens: 1
      key-resolver: "#{@userKeyResolver}"

熔断

filters:
  - name: CircuitBreaker
    args:
      name: myCircuitBreaker
      fallbackUri: forward:/fallback
      statusCodes:
        - BAD_GATEWAY
        - SERVICE_UNAVAILABLE

自定义过滤器

GlobalFilter(全局过滤器)

@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 前置处理
        ServerHttpRequest request = exchange.getRequest().mutate()
            .header("X-Global-Filter", "true")
            .build();
        // 继续链式处理
        return chain.filter(exchange.mutate().request(request).build())
            .then(Mono.fromRunnable(() -> {
                // 后置处理
                ServerHttpResponse response = exchange.getResponse();
                response.getHeaders().add("X-Global-Filter", "processed");
            }));
    }
    @Override
    public int getOrder() {
        return -1; // 优先级,数值越小优先级越高
    }
}

GatewayFilter(路由过滤器)

@Component
public class CustomGatewayFilterFactory 
    extends AbstractGatewayFilterFactory<CustomGatewayFilterFactory.Config> {
    public CustomGatewayFilterFactory() {
        super(Config.class);
    }
    @Override
    public String name() {
        return "CustomFilter";
    }
    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            // 获取配置
            String param = config.getParam();
            // 修改请求
            ServerHttpRequest request = exchange.getRequest();
            // 自定义逻辑
            return chain.filter(exchange);
        };
    }
    @Validated
    public static class Config {
        private String param;
        // getter/setter
    }
}

完整配置示例

spring:
  cloud:
    gateway:
      routes:
        # 用户服务路由
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
            - Method=GET,POST,PUT,DELETE
            - Header=X-Request-Source, web|mobile
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Gateway-Source, gateway
            - name: Retry
              args:
                retries: 2
                statuses: BAD_GATEWAY
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100
                redis-rate-limiter.burstCapacity: 200
                key-resolver: "#{@ipKeyResolver}"
        # 订单服务路由(灰度发布)
        - id: order-service-v1
          uri: lb://order-service-v1
          predicates:
            - Path=/api/order/**
            - Weight=order-service, 80
          filters:
            - StripPrefix=1
            - AddResponseHeader=X-Version, v1
        - id: order-service-v2
          uri: lb://order-service-v2
          predicates:
            - Path=/api/order/**
            - Weight=order-service, 20
            - Header=X-Version, v2
          filters:
            - StripPrefix=1
            - AddResponseHeader=X-Version, v2
        # 回退路由
        - id: fallback
          uri: forward:/fallback
          predicates:
            - Path=/fallback
      # 全局过滤器配置
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Origin
      # CORS配置
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOrigins: "https://example.com"
            allowedMethods:
              - GET
              - POST
            allowedHeaders: "*"

性能优化建议

  1. 合理使用断言顺序:将命中率高的断言放在前面
  2. 避免过多过滤器:每个过滤器都会增加处理开销
  3. 使用异步处理:尽量使用非阻塞操作
  4. 缓存处理:对于重复计算的结果进行缓存
  5. 监控和日志:合理配置日志级别,避免过多日志影响性能

常见问题解决

  1. 404错误:检查路由断言是否匹配
  2. 超时问题:配置熔断和降级策略
  3. 请求头丢失:检查是否需要配置过滤器
  4. 循环路由:避免路由到自身服务

这个框架提供了强大的路由和过滤能力,能够满足大部分API网关需求,根据实际业务场景选择合适的断言和过滤器组合即可。

抱歉,评论功能暂时关闭!