Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南

简介: 本文详细介绍了 Spring Cloud Gateway 的核心功能与实践配置。首先讲解了网关模块的创建流程,包括依赖引入(gateway、nacos 服务发现、负载均衡)、端口与服务发现配置,以及路由规则的设置(需注意路径前缀重复与优先级 order)。接着深入解析路由断言,涵盖 After、Before、Path 等 12 种内置断言的参数、作用及配置示例,并说明了自定义断言的实现方法。随后重点阐述过滤器机制,区分路由过滤器(如 AddRequestHeader、RewritePath、RequestRateLimiter 等)与全局过滤器的作用范围与配置方式,提

Gateway

创建网关模块

引入相关依赖

    <dependencies>
        <!--引入gateway网关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--引入nacos的服务发现,将网关注册到配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--引入nacos负载均衡的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>        
    </dependencies>

配置端口和服务发现

spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
server:
  port: 88

配置路由

在配置路由时,我们要注意,配置越靠前,就会优先被匹配,所以我们配置时,==尽量避免路径前缀的重复==,如果重复不可避免,我们要配置路由的==优先级order==。

spring:
  cloud:
    gateway:
      routes:
        - id: service-order           # 服务的名字
          uri: lb://service-order     # 负载均衡访问服务的地址
          predicates:                 # 断言
            - Path=/api/order/**      # 服务的映射路径
        - id: service-product
          uri: lb://service-product
          predicates:
            - Path=/api/product/**
          order: 0                      # 数值越小,优先等级越高
       #  filters:                      # 配置过滤器

此时简单的网关配置就已经配置完成了,对外暴露88端口,会根据路径的不同,负载均衡的映射到配置的服务上

路由工作原理

image-20250901170859597

路由断言格式

官网地址:Spring Cloud Gateway断言工厂

短写法:

spring:
  cloud:
    gateway:
      routes:
        - id: service-order           # 服务的名字
          uri: lb://service-order     # 负载均衡访问服务的地址
          predicates:                 # 断言
            - Path=/api/order/**      # 服务的映射路径

全写法:

spring:
  cloud:
    gateway:
      routes:
        - id: service-order           # 服务的名字
          uri: lb://service-order     # 负载均衡访问服务的地址
          predicates:                 # 断言
            - name: Path              # 断言规则的名字
              args:
                patterns: /api/order/**     # 路径规则
                matchTrailingSlash: false   # 路径中或末尾,加/和不加/是两种路径(默认为true)

快速查询断言规则

项目全局搜索:RoutePredicateFactory

进入类后,使用快捷键:ctrl+h打开列表,此时看到抽象的工厂中,去掉后缀RoutePredicateFactory剩余部分,就是我们可以写的断言

断言(predicates)

1. After

  • 参数:1个,类型为 datetime(格式为 ZonedDateTime,如 2025-09-03T10:00:00+08:00[Asia/Shanghai])。

  • 作用:仅匹配「指定时间之后」的请求。

  • 示例配置

    spring:
      cloud:
        gateway:
          routes:
            - id: after_route
              uri: http://localhost:8081
              predicates:
                - After=2025-09-03T10:00:00+08:00[Asia/Shanghai]
    
  • 说明:只有2025年9月3日10:00之后的请求,才会路由到 http://localhost:8081

2. Before

  • 参数:1个,类型为 datetime

  • 作用:仅匹配「指定时间之前」的请求。

  • 示例配置

    spring:
      cloud:
        gateway:
          routes:
            - id: before_route
              uri: http://localhost:8082
              predicates:
                - Before=2025-09-10T23:59:59+08:00[Asia/Shanghai]
    
  • 说明:2025年9月10日23:59:59之前的请求,会路由到 http://localhost:8082

3. Between

  • 参数:2个,类型均为 datetime

  • 作用:仅匹配「两个指定时间区间内」的请求。

  • 示例配置

    spring:
      cloud:
        gateway:
          routes:
            - id: between_route
              uri: http://localhost:8083
              predicates:
                - Between=2025-09-03T00:00:00+08:00[Asia/Shanghai], 2025-09-05T23:59:59+08:00[Asia/Shanghai]
    
  • 说明:2025年9月3日~9月5日之间的请求,会路由到 http://localhost:8083

4. Cookie

  • 参数:2个,类型为 string(Cookie名)、regexp(Cookie值的正则表达式)。

  • 作用:请求需包含「指定名称的Cookie」,且Cookie值匹配正则

  • 示例配置

    spring:
      cloud:
        gateway:
          routes:
            - id: cookie_route
              uri: http://localhost:8084
              predicates:
                - Cookie=userToken, ^[a-zA-Z0-9]{
         16}$
    
  • 说明:请求必须携带名为 userToken 的Cookie,且值为「16位字母/数字组合」,才会路由到 http://localhost:8084

5. Header

  • 参数:2个,类型为 string(请求头名)、regexp(请求头值的正则表达式)。

  • 作用:请求需包含「指定名称的请求头」,且值匹配正则

  • 示例配置

    spring:
      cloud:
        gateway:
          routes:
            - id: header_route
              uri: http://localhost:8085
              predicates:
                - Header=Content-Type, application/json
    
  • 说明:请求头 Content-Type 的值为 application/json 时,路由到 http://localhost:8085

6. Host

  • 参数N 个,类型为 string(可指定多个Host值,支持通配符)。

  • 作用:请求的 Host 头必须是「指定的枚举值」(如域名、带通配符的子域名)。

  • 示例配置

    spring:
      cloud:
        gateway:
          routes:
            - id: host_route
              uri: http://localhost:8086
              predicates:
                - Host=api.example.com, *.test.com
    
  • 说明:若请求 Hostapi.example.com,或任意 *.test.com 子域名(如 user.test.com),则路由到 http://localhost:8086

7. Method

  • 参数N 个,类型为 string(HTTP方法,如 GET/POST/PUT 等)。

  • 作用:请求方法必须是「指定的枚举值」。

  • 示例配置

    spring:
      cloud:
        gateway:
          routes:
            - id: method_route
              uri: http://localhost:8087
              predicates:
                - Method=POST, PUT
    
  • 说明:只有 POSTPUT 方法的请求,才会路由到 http://localhost:8087

8. Path

  • 参数:2个,类型为 List<String>(路径模式,支持通配符 */**)、bool(可选,是否匹配末尾的 /)。

  • 作用:请求路径需匹配指定规则(如前缀、通配符路径)。

  • 示例配置

    spring:
      cloud:
        gateway:
          routes:
            - id: path_route
              uri: http://localhost:8088
              predicates:
                - Path=/api/product/**, true
    
  • 说明:路径以 /api/product/ 开头(支持多层子路径,如 /api/product/123/detail),且匹配末尾的 /true 为可选配置,控制末尾斜杠匹配),则路由到 http://localhost:8088

9. Query

  • 参数:2个,类型为 string(查询参数名)、regexp(参数值的正则表达式,可选)。

  • 作用:场景1:请求需包含「指定查询参数」(无论值是什么);场景2:参数值匹配正则

  • 示例1(仅检查参数存在)

    spring:
      cloud:
        gateway:
          routes:
            - id: query_route1
              uri: http://localhost:8089
              predicates:
                - Query=token
    
    • 说明:请求包含 token 参数(值任意),则路由到 http://localhost:8089
  • 示例2(参数值匹配正则)

    spring:
      cloud:
        gateway:
          routes:
            - id: query_route2
              uri: http://localhost:9000
              predicates:
                - Query=age, \d+
    
    • 说明:请求包含 age 参数,且值为「数字」,则路由到 http://localhost:9000

10. RemoteAddr

  • 参数:1个,类型为 List<String>(CIDR格式的IP/网段,可多个)。

  • 作用:请求的客户端IP需属于「指定网络域」(CIDR格式,如 192.168.1.0/24 表示网段,10.0.0.5/32 表示单个IP)。

  • 示例配置

    spring:
      cloud:
        gateway:
          routes:
            - id: remoteaddr_route
              uri: http://localhost:9001
              predicates:
                - RemoteAddr=192.168.1.0/24, 10.0.0.5/32
    
  • 说明:若客户端IP在 192.168.1.0~192.168.1.255 网段,或等于 10.0.0.5,则路由到 http://localhost:9001

11. Weight

  • 参数:2个,类型为 string(分组名)、int(权重值)。

  • 作用:对同一路由ID的多个目标服务,按「权重比例」分配流量(负载均衡场景)。

  • 示例配置(需配置两个同ID的路由,模拟权重分配):

    spring:
      cloud:
        gateway:
          routes:
            - id: weight_group
              uri: http://localhost:9002
              predicates:
                - Weight=group1, 8
            - id: weight_group
              uri: http://localhost:9003
              predicates:
                - Weight=group1, 2
    
  • 说明group1 分组下,http://localhost:9002 分配80%流量,http://localhost:9003 分配20%流量。

12. XForwardedRemoteAddr

  • 参数:1个,类型为 List<String>(CIDR格式的IP/网段)。

  • 作用:从 X-Forwarded-For 请求头解析客户端IP,并判断是否属于「指定网络域」。

  • 示例配置

    spring:
      cloud:
        gateway:
          routes:
            - id: xforwarded_route
              uri: http://localhost:9004
              predicates:
                - XForwardedRemoteAddr=192.168.2.0/24
    
  • 说明:从 X-Forwarded-For 头中提取客户端IP,若属于 192.168.2.0/24 网段,则路由到 http://localhost:9004(常用于代理场景下的IP校验)。

自定义断言

由于在开发过程中,可能gateway给我们提供的断言工厂不能满足我们的需求,所以需要我们自己去创建一个适合我们业务需求的断言,因此自定义断言由此而生。

需求:满足以下定义的断言规则,由于vip规则不存在,所以需要我们自行创建断言规则

spring:
  cloud:
    gateway:
      routes:
        - id: bing
          uri: https://cn.bing.com
          predicates:
            - Path=/search
            - Query=q,haha
            - Vip=user,nf

自定义断言工厂VipRoutePredicateFactory

@Component
public class VipRoutePredicateFactory extends AbstractRoutePredicateFactory<VipRoutePredicateFactory.Config> {
   

    //需要有一个无参构造器
    public VipRoutePredicateFactory() {
   
        super(VipRoutePredicateFactory.Config.class);
    }

    //提供一个短写法的顺序方法
    @Override
    public List<String> shortcutFieldOrder() {
   
        return Arrays.asList("param","value");
    }

    //之后需要实现断言的逻辑规则
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
   
        return new GatewayPredicate() {
                            //需要new一个网关的断言类
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
         //这个对象里边封装了所有的请求和响应对象

                ServerHttpRequest request = serverWebExchange.getRequest();     //拿到请求

                String first = request.getQueryParams().getFirst(config.param);     //获取请求参数为config.param值的请求参数

                return StringUtils.hasText(first) && first.equals(config.value);     //判断值是否为空,且是否与config.value的值相等
            }
        };
    }

    /**
     * 可以配置的参数
     */
    @Validated
    public static class Config {
           //需要一个内部类
        private @NotEmpty String param;

        private @NotEmpty String value;

        //编写这两个值的get和set方法
        public String getParam() {
   
            return param;
        }
        public void setParam(String param) {
   
            this.param = param;
        }
        public String getValue() {
   
            return value;
        }
        public void setValue(String value) {
   
            this.value = value;
        }
    }

}

过滤器

1、Gateway 过滤器基础概述

1.1 过滤器的两种类型

Spring Cloud Gateway 的过滤器分为全局过滤器和路由过滤器两类,具体区别如下:

过滤器类型 作用范围 配置方式 典型应用场景
全局过滤器(GlobalFilter) 对所有路由生效 无需配置,通过代码实现 全局鉴权、日志记录、跨域处理
路由过滤器(GatewayFilter) 仅对特定路由生效 通过配置绑定到路由 路由级别的请求修改、限流、熔断

1.2 过滤器的生命周期

Gateway 过滤器的生命周期只有两个阶段:

  • Pre 阶段:在请求被路由到目标服务之前执行。可用于身份验证、请求参数修改、日志记录等
  • Post 阶段:在目标服务返回响应之后执行。可用于修改响应内容、添加响应头、收集统计信息等

请求处理流程如下:

客户端请求 → Pre过滤器链 → 路由转发 → 目标服务 → Post过滤器链 → 返回响应

1.3 过滤器的执行顺序

过滤器的执行顺序由 @Order 注解或 Ordered 接口实现决定,值越小优先级越高。当全局过滤器与路由过滤器混合使用时,需通过 @Order 明确优先级以避免执行顺序混乱。

2、常用路由过滤器详解

2.1 AddRequestHeader 过滤器

作用:为请求添加指定的请求头。

配置示例

spring:
  cloud:
    gateway:
      routes:
        - id: add_request_header_route
          uri: http://example.org
          predicates:
            - Path=/hello/**
          filters:
            - AddRequestHeader=X-Request-Id, 12345
            - AddRequestHeader=X-User-Type, VIP

案例说明:上述配置会为所有匹配 /hello/** 路径的请求添加两个请求头:X-Request-Id: 12345X-User-Type: VIP,下游服务可以通过读取这些请求头获取相关信息。

2.2 AddResponseHeader 过滤器

作用:为响应添加指定的响应头。

配置示例

spring:
  cloud:
    gateway:
      routes:
        - id: add_response_header_route
          uri: http://example.org
          predicates:
            - Path=/api/**
          filters:
            - AddResponseHeader=X-Response-From, gateway
            - AddResponseHeader=Cache-Control, no-store

案例说明:该配置会为所有从 /api/** 路径返回的响应添加 X-Response-From: gateway 头,标识该响应经过网关处理,同时添加缓存控制头 Cache-Control: no-store 指示客户端不缓存响应。

2.3 RewritePath 过滤器

作用:重写请求路径。

配置示例

spring:
  cloud:
    gateway:
      routes:
        - id: rewrite_path_route
          uri: http://example.org
          predicates:
            - Path=/api/**
          filters:
            - RewritePath=/api/(?<segment>.*), /service/$\{segment}

案例说明:该配置会将 /api/xxx 形式的请求路径重写为 /service/xxx。例如,客户端请求 /api/user/1 会被转发到后端服务的 /service/user/1 路径。

新手提示:配置中的$\{segment}需要使用$加转义符\,在 YAML 中需写成$\{segment},而在 Properties 文件中直接使用${segment}

2.4 PrefixPath 过滤器

作用:为请求路径添加前缀。

配置示例

spring:
  cloud:
    gateway:
      routes:
        - id: prefix_path_route
          uri: http://example.org
          predicates:
            - Path=/hello
          filters:
            - PrefixPath=/api/v1

案例说明:该配置会为请求路径添加 /api/v1 前缀。当客户端请求 /hello 时,实际会转发到后端服务的 /api/v1/hello 路径。

2.5 StripPrefix 过滤器

作用:移除路径中的指定前缀。

配置示例

spring:
  cloud:
    gateway:
      routes:
        - id: strip_prefix_route
          uri: http://example.org
          predicates:
            - Path=/v1/**
          filters:
            - StripPrefix=1

案例说明StripPrefix=1 表示移除路径中的第一个前缀。当客户端请求 /v1/user/1 时,实际会转发到后端服务的 /user/1 路径。如果设置 StripPrefix=2,则会移除前两个前缀。

2.6 RequestRateLimiter 过滤器

作用:基于令牌桶算法实现请求限流,保护后端服务。

配置示例

spring:
  redis:
    host: localhost
    port: 6379
  cloud:
    gateway:
      routes:
        - id: rate_limiter_route
          uri: lb://order-service
          predicates:
            - Path=/order/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10  # 令牌桶每秒填充速率
                redis-rate-limiter.burstCapacity: 20  # 令牌桶总容量
                key-resolver: "#{@userKeyResolver}"    # 限流键解析器

Java 配置(定义 KeyResolver):

@Configuration
public class RateLimiterConfig {
   
    /**
     * 根据用户ID进行限流
     */
    @Bean
    public KeyResolver userKeyResolver() {
   
        return exchange -> Mono.just(
            Objects.requireNonNullElse(
                exchange.getRequest().getQueryParams().getFirst("userId"),
                "anonymous"  // 未提供userId时使用匿名用户
            )
        );
    }
}

案例说明:该配置实现了基于用户的限流策略,每个用户每秒允许 10 个请求,突发情况下最多允许 20 个请求。需要引入 spring-boot-starter-data-redis-reactive 依赖支持 Redis 限流实现。当请求被限流时,网关会返回 HTTP 429 - Too Many Requests 状态码。

扩展配置:如果需要根据 IP 地址限流,可修改 KeyResolver:

@Bean
public KeyResolver ipKeyResolver() {
   
    return exchange -> Mono.just(
        exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
    );
}

2.7 Retry 过滤器

作用:实现请求重试机制,提高服务可用性。

配置示例

spring:
  cloud:
    gateway:
      routes:
        - id: retry_route
          uri: http://example.org
          predicates:
            - Path=/service/**
          filters:
            - name: Retry
              args:
                retries: 3                  # 重试次数
                statuses: BAD_GATEWAY       # 需要重试的状态码
                methods: GET,POST           # 需要重试的HTTP方法
                backoff:
                  firstBackoff: 100ms       # 首次重试延迟
                  maxBackoff: 1000ms        # 最大重试延迟
                  factor: 2                  # 延迟倍数
                  basedOnPreviousValue: false

案例说明:该配置表示当后端服务返回 502 Bad Gateway 状态码时,网关会自动重试请求,最多重试 3 次。重试延迟依次为 100ms、200ms、400ms(按 2 倍因子递增)。

注意事项:重试机制可能会导致后端服务接收到重复请求,因此要确保接口的幂等性。

2.8 CircuitBreaker 过滤器

作用:实现服务熔断,防止故障扩散。

配置示例

spring:
  cloud:
    gateway:
      routes:
        - id: circuit_breaker_route
          uri: lb://payment-service
          predicates:
            - Path=/payment/**
          filters:
            - name: CircuitBreaker
              args:
                name: paymentServiceCircuitBreaker
                fallbackUri: forward:/fallback/payment

fallback 控制器

@RestController
public class FallbackController {
   
    @GetMapping("/fallback/payment")
    public ResponseEntity<String> paymentFallback() {
   
        return ResponseEntity.ok("支付服务暂时不可用,请稍后再试");
    }
}

案例说明:当 payment-service 服务出现故障或响应超时,断路器会被触发,请求会被转发到 /fallback/payment 路径,返回友好的 fallback 响应,避免客户端收到错误信息。

3、全局过滤器详解

3.1 内置全局过滤器

Spring Cloud Gateway 内置了多个全局过滤器,主要包括:

  • NettyWriteResponseFilter:处理响应写入
  • RouteToRequestUrlFilter:将路由 URI 转换为请求 URL
  • LoadBalancerClientFilter:负载均衡过滤器
  • WebsocketRoutingFilter:WebSocket 路由支持

这些过滤器会自动生效,无需额外配置。

3.2 自定义全局过滤器:令牌认证过滤器

作用:验证所有请求中的令牌,实现全局身份认证。

@Component
@Order(-100)  // 优先级较高,确保在路由前执行
public class TokenAuthFilter implements GlobalFilter, Ordered {
   

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
   
        // 从请求参数中获取token
        String token = exchange.getRequest().getQueryParams().getFirst("token");

        // 验证token
        if (token == null || !token.startsWith("valid_")) {
   
            // 未提供有效token,返回401 Unauthorized
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        // token验证通过,继续执行过滤器链
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
   
        return -100;  // 与@Order注解一致
    }
}

案例说明:该过滤器会检查所有请求的 token 参数,只有携带以 valid_ 开头的令牌的请求才能通过验证。实际应用中,可以扩展该过滤器实现 JWT 令牌验证等更复杂的认证逻辑。

3.3 自定义全局过滤器:全局日志过滤器

作用:记录所有请求的详细信息和响应状态,用于审计和调试。

@Component
@Order(-200)
public class GlobalLoggingFilter implements GlobalFilter, Ordered {
   

    private static final Logger logger = LoggerFactory.getLogger(GlobalLoggingFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
   
        // Pre阶段:记录请求信息
        ServerHttpRequest request = exchange.getRequest();
        long startTime = System.currentTimeMillis();
        logger.info("Request: {} {} from {}",
                   request.getMethod(),
                   request.getURI(),
                   request.getRemoteAddress());

        // Post阶段:记录响应信息
        return chain.filter(exchange)
            .then(Mono.fromRunnable(() -> {
   
                ServerHttpResponse response = exchange.getResponse();
                long duration = System.currentTimeMillis() - startTime;
                logger.info("Response: {} {} completed in {}ms",
                           request.getMethod(),
                           request.getURI(),
                           duration);
                logger.info("Response status: {}", response.getStatusCode());
            }));
    }

    @Override
    public int getOrder() {
   
        return -200;
    }
}

案例说明:该过滤器在 Pre 阶段记录请求方法、路径和客户端 IP,在 Post 阶段记录请求处理时长和响应状态码,帮助开发人员了解请求处理情况和系统性能。

3.4 自定义全局过滤器:跨域处理过滤器

作用:处理跨域资源共享(CORS)请求。

@Component
@Order(-300)
public class CorsFilter implements GlobalFilter, Ordered {
   

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
   
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        // 设置跨域响应头
        response.getHeaders().add("Access-Control-Allow-Origin", "*");
        response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.getHeaders().add("Access-Control-Allow-Headers", "Content-Type, Authorization");
        response.getHeaders().add("Access-Control-Max-Age", "3600");

        // 处理预检请求
        if (request.getMethod() == HttpMethod.OPTIONS) {
   
            response.setStatusCode(HttpStatus.OK);
            return response.setComplete();
        }

        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
   
        return -300;
    }
}

案例说明:该过滤器为所有响应添加 CORS 头,允许任何源的跨域请求,并支持常见的 HTTP 方法。对于 OPTIONS 预检请求,直接返回 200 OK 状态。

注意:在生产环境中,应将Access-Control-Allow-Origin设置为具体的允许域名,而不是通配符*,以提高安全性。

4、过滤器实战案例

4.1 微服务认证授权流程:JWT 验证全局过滤器

结合路由过滤器和全局过滤器实现完整的认证授权流程,首先实现 JWT 验证全局过滤器:

@Component
@Order(-100)
public class JwtAuthFilter implements GlobalFilter, Ordered {
   

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
   
        // 从请求头获取Authorization
        String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization");

        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
   
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        String token = authHeader.substring(7);
        try {
   
            // 验证JWT令牌
            Claims claims = JwtUtils.verifyToken(token);
            // 将用户ID添加到请求头
            ServerHttpRequest modifiedRequest = exchange.getRequest()
                .mutate()
                .header("X-User-Id", claims.getSubject())
                .build();
            return chain.filter(exchange.mutate().request(modifiedRequest).build());
        } catch (Exception e) {
   
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
    }

    @Override
    public int getOrder() {
   
        return -100;
    }
}

4.2 微服务认证授权流程:路由级权限配置

配置路由级权限控制:

spring:
  cloud:
    gateway:
      routes:
        - id: admin_service_route
          uri: lb://admin-service
          predicates:
            - Path=/admin/**
          filters:
            - name: AdminPermissionFilter  # 自定义路由过滤器
              args:
                requiredRole: ADMIN
        - id: user_service_route
          uri: lb://user-service
          predicates:
            - Path=/user/**
          filters:
            - name: UserPermissionFilter
              args:
                requiredRole: USER

4.3 微服务认证授权流程:AdminPermissionFilter 实现

实现 AdminPermissionFilter 路由过滤器:

@Component
public class AdminPermissionFilter extends AbstractGatewayFilterFactory<AdminPermissionFilter.Config> {
   

    public AdminPermissionFilter() {
   
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
   
        return (exchange, chain) -> {
   
            // 从请求头获取用户角色
            String userRole = exchange.getRequest().getHeaders().getFirst("X-User-Role");

            if (userRole == null || !userRole.equals(config.getRequiredRole())) {
   
                exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
                return exchange.getResponse().setComplete();
            }

            return chain.filter(exchange);
        };
    }

    public static class Config {
   
        private String requiredRole;

        // getter和setter
        public String getRequiredRole() {
    return requiredRole; }
        public void setRequiredRole(String requiredRole) {
    this.requiredRole = requiredRole; }
    }
}

4.4 接口限流与熔断组合方案

结合 RequestRateLimiter 和 CircuitBreaker 过滤器保护高并发接口:

spring:
  redis:
    host: localhost
    port: 6379
  cloud:
    gateway:
      routes:
        - id: high_traffic_route
          uri: lb://product-service
          predicates:
            - Path=/products/hot/**
          filters:
            # 1. 限流过滤器
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100
                redis-rate-limiter.burstCapacity: 200
                key-resolver: "#{@ipKeyResolver}"
            # 2. 熔断过滤器
            - name: CircuitBreaker
              args:
                name: productServiceCircuitBreaker
                fallbackUri: forward:/fallback/products
            # 3. 请求超时设置
            - name: RequestTimeOut
              args:
                timeout: 3000ms

说明:该配置为热门商品接口提供了三层保护:

  1. 限流:每个 IP 每秒最多处理 100 个请求
  2. 熔断:服务响应异常时触发 fallback
  3. 超时控制:请求超过 3 秒未响应则超时

5、过滤器使用最佳实践

5.1 性能优化建议

  1. 避免耗时操作:过滤器中应避免执行耗时操作(如同步远程调用),以免影响网关性能
  2. 合理设置过滤器顺序:通过 @Order 注解明确过滤器执行顺序,避免混乱
  3. 异步处理:利用 Spring WebFlux 的响应式编程模型,使用 Mono 和 Flux 进行异步处理
  4. 选择性应用过滤器:路由过滤器应仅应用于需要的路由,避免不必要的性能开销

5.2 常见问题解决方案

  1. 过滤器执行顺序问题

    • 使用 @Order 注解明确定义顺序
    • 全局过滤器和路由过滤器统一按 Order 值排序
    • 优先级:-200 > -100 > 0 > 100
  2. 过滤器链中断问题

    • 确保每个过滤器都调用 chain.filter(exchange) 继续过滤器链
    • 异常情况下使用 exchange.getResponse().setComplete() 终止请求
  3. 请求参数修改问题

    • 使用 ServerHttpRequestDecorator 修改请求参数
    • 注意:请求体(body)修改需要特殊处理

5.3 调试与监控

  1. 日志配置:通过设置日志级别为 DEBUG 查看过滤器执行情况
logging:
  level:
    org.springframework.cloud.gateway: DEBUG
  1. actuator 监控:启用 actuator 端点监控网关状态
management:
  endpoints:
    web:
      exposure:
        include: gateway,health,info

访问 http://localhost:8080/actuator/gateway/filters 可查看所有过滤器信息。

6、总结

Spring Cloud Gateway 过滤器是实现网关核心功能的关键组件,通过灵活使用路由过滤器和全局过滤器,我们可以实现认证授权、限流熔断、日志监控等多种功能。本文介绍了常用过滤器的配置和使用案例,包括:

  • 路由过滤器:AddRequestHeader、RewritePath、RequestRateLimiter 等
  • 全局过滤器:自定义认证、日志、跨域处理过滤器
  • 实战案例:微服务认证授权流程、限流熔断组合方案

过滤器的设计遵循 "单一职责" 原则,每个过滤器专注于实现特定功能,通过过滤器链的方式组合使用,既保证了灵活性,又提高了可维护性。

作为初学者,建议从基础过滤器开始实践,逐步掌握自定义过滤器的实现方法,最终能够根据实际业务需求设计和实现复杂的网关过滤逻辑。

附录:常用过滤器速查表

过滤器类型 作用 核心参数 适用场景
AddRequestHeader 添加请求头 name, value 身份传递、环境标识
AddResponseHeader 添加响应头 name, value 安全头、缓存控制
RewritePath 重写路径 regexp, replacement 路径转换、版本控制
StripPrefix 移除路径前缀 parts API 版本管理
RequestRateLimiter 请求限流 replenishRate, burstCapacity 流量控制
Retry 请求重试 retries, statuses 提高可用性
CircuitBreaker 服务熔断 name, fallbackUri 故障隔离
RedirectTo 重定向 status, url 路由跳转、维护页
SetPath 设置路径 template 路径重写
相关文章
|
4月前
|
Java 关系型数据库 MySQL
Spring Boot自动配置:魔法背后的秘密
Spring Boot 自动配置揭秘:只需简单配置即可启动项目,背后依赖“约定大于配置”与条件化装配。核心在于 `@EnableAutoConfiguration` 注解与 `@Conditional` 系列条件判断,通过 `spring.factories` 或 `AutoConfiguration.imports` 加载配置类,实现按需自动装配 Bean。
|
4月前
|
缓存 安全 Java
Spring Security通用权限管理模型解析
Spring Security作为Spring生态的核心安全框架,结合RBAC与ACL权限模型,基于IoC与AOP构建灵活、可扩展的企业级权限控制体系,涵盖认证、授权流程及数据库设计、性能优化等实现策略。
313 0
|
4月前
|
缓存 安全 Java
Spring Security权限管理解析
Spring Security是Spring生态中的核心安全框架,采用认证与授权分离架构,提供高度可定制的权限管理方案。其基于过滤器链实现认证流程,通过SecurityContextHolder管理用户状态,并结合RBAC模型与动态权限决策,支持细粒度访问控制。通过扩展点如自定义投票器、注解式校验与前端标签,可灵活适配多租户、API网关等复杂场景。结合缓存优化与无状态设计,适用于高并发与前后端分离架构。
353 0
|
4月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
1558 0
|
3月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
Spring Boot 3.x 微服务架构实战指南
|
3月前
|
XML Java 数据格式
《深入理解Spring》:AOP面向切面编程深度解析
Spring AOP通过代理模式实现面向切面编程,将日志、事务等横切关注点与业务逻辑分离。支持注解、XML和编程式配置,提供五种通知类型及丰富切点表达式,助力构建高内聚、低耦合的可维护系统。
|
3月前
|
缓存 JSON NoSQL
别再手写过滤器!SpringCloud Gateway 内置30 个,少写 80% 重复代码
小富分享Spring Cloud Gateway内置30+过滤器,涵盖请求、响应、路径、安全等场景,无需重复造轮子。通过配置实现Header处理、限流、重试、熔断等功能,提升网关开发效率,避免代码冗余。
417 1
|
3月前
|
前端开发 Java 应用服务中间件
《深入理解Spring》 Spring Boot——约定优于配置的革命者
Spring Boot基于“约定优于配置”理念,通过自动配置、起步依赖、嵌入式容器和Actuator四大特性,简化Spring应用的开发与部署,提升效率,降低门槛,成为现代Java开发的事实标准。
|
3月前
|
缓存 安全 Java
《深入理解Spring》过滤器(Filter)——Web请求的第一道防线
Servlet过滤器是Java Web核心组件,可在请求进入容器时进行预处理与响应后处理,适用于日志、认证、安全、跨域等全局性功能,具有比Spring拦截器更早的执行时机和更广的覆盖范围。

热门文章

最新文章