Spring Cloud Gateway微服务网关路由过滤与限流熔断配置实战

Spring Cloud Gateway在微服务架构中的定位

Spring Cloud Gateway是Spring官方推出的微服务网关组件,基于Spring WebFlux和Reactor实现非阻塞式请求转发。在微服务架构中,网关层承担统一路由、限流熔断、认证鉴权、日志监控等横切职责。相比Netflix Zuul,Spring Cloud Gateway基于Netty异步非阻塞模型,在高并发场景下吞吐性能显著优于基于Servlet的Zuul 1.x。

Spring Cloud Gateway的核心概念:Route(路由)由ID、目标URI、Predicate(断言)和Filter(过滤器)组成;Predicate用于匹配HTTP请求的路径、Header、参数等条件;Filter在请求转发前后对请求和响应进行修改处理。Gateway通过Spring Cloud LoadBalancer集成服务发现,实现基于服务名的动态路由。

Gateway基础路由配置

使用Spring Boot 3.x和Spring Cloud Gateway搭建网关服务:

<!-- pom.xml -->
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

YAML配置路由规则:

# application.yml
server:
  port: 8080

spring:
  cloud:
    gateway:
      # 路由配置
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
            - Method=GET,POST
          filters:
            - StripPrefix=2

        - id: product-service
          uri: lb://product-service
          predicates:
            - Path=/api/products/**
            - Header=X-API-Version, v[1-9]
          filters:
            - StripPrefix=2
            - AddResponseHeader=X-Gateway, scg

      # 全局过滤器
      default-filters:
        - AddRequestHeader=X-Gateway-Request, true
        - AddResponseHeader=X-Gateway-Response, true

      # 服务发现配置
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true

  # Redis用于限流
  data:
    redis:
      host: 192.168.1.100
      port: 6379
      password: yourpassword

自定义全局过滤器实现认证鉴权

通过实现GlobalFilter和Ordered接口创建全局过滤器,在请求转发前进行JWT令牌验证:

@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    private static final List<String> WHITE_LIST = List.of(
        "/api/auth/login",
        "/api/auth/register",
        "/api/auth/refresh"
    );

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();

        // 白名单路径直接放行
        if (WHITE_LIST.stream().anyMatch(path::startsWith)) {
            return chain.filter(exchange);
        }

        // 提取Authorization头
        String authHeader = request.getHeaders().getFirst("Authorization");
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            return unauthorizedResponse(exchange, "Missing or invalid token");
        }

        String token = authHeader.substring(7);

        try {
            // 验证JWT令牌
            Claims claims = Jwts.parserBuilder()
                .setSigningKey(Keys.hmacShaKeyFor(secretKey.getBytes()))
                .build()
                .parseClaimsJws(token)
                .getBody();

            // 将用户信息注入请求头,传递给下游服务
            ServerHttpRequest mutatedRequest = request.mutate()
                .header("X-User-Id", claims.getSubject())
                .header("X-User-Role", claims.get("role", String.class))
                .build();

            return chain.filter(exchange.mutate().request(mutatedRequest).build());

        } catch (ExpiredJwtException e) {
            return unauthorizedResponse(exchange, "Token expired");
        } catch (JwtException e) {
            return unauthorizedResponse(exchange, "Invalid token");
        }
    }

    private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String message) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);

        String body = String.format("{"code":401,"message":"%s"}", message);
        DataBuffer buffer = response.bufferFactory().wrap(body.getBytes());
        return response.writeWith(Mono.just(buffer));
    }

    @Override
    public int getOrder() {
        return -100;  // 最高优先级
    }
}

RequestRateLimiter限流配置与自定义限流策略

Spring Cloud Gateway内置RequestRateLimiter过滤器,基于Redis令牌桶算法实现限流。通过自定义KeyResolver实现不同维度的限流策略:

@Configuration
public class RateLimiterConfig {

    // 按用户ID限流
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> {
            String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");
            return Mono.just(userId != null ? userId : "anonymous");
        };
    }

    // 按IP地址限流
    @Bean
    public KeyResolver ipKeyResolver() {
        return exchange -> {
            String ip = exchange.getRequest().getRemoteAddress() != null
                ? exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
                : "unknown";
            return Mono.just(ip);
        };
    }

    // 按API路径限流
    @Bean
    public KeyResolver apiKeyResolver() {
        return exchange -> Mono.just(
            exchange.getRequest().getURI().getPath()
        );
    }

    // 按用户+API组合限流
    @Bean
    public KeyResolver userApiKeyResolver() {
        return exchange -> {
            String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");
            String apiPath = exchange.getRequest().getURI().getPath();
            return Mono.just(userId + ":" + apiPath);
        };
    }

    // 自定义RedisRateLimiter配置
    @Bean
    public RedisRateLimiter customRateLimiter(RedisConnectionFactory factory) {
        // replenishRate: 令牌填充速率(每秒10个)
        // burstCapacity: 令牌桶容量(最大20个)
        return new RedisRateLimiter(10, 20);
    }
}

在路由配置中指定限流策略:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service-rate-limited
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                key-resolver: "#{@userApiKeyResolver}"
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20
                redis-rate-limiter.requestedTokens: 1

集成Resilience4j实现熔断降级

Spring Cloud Gateway集成Resilience4j实现熔断和重试机制,在下游服务不可用时快速失败并返回降级响应:

# application.yml
resilience4j:
  circuitbreaker:
    configs:
      default:
        sliding-window-size: 100
        sliding-window-type: COUNT_BASED
        minimum-number-of-calls: 20
        failure-rate-threshold: 50
        wait-duration-in-open-state: 10s
        permitted-number-of-calls-in-half-open-state: 5
        automatic-transition-from-open-to-half-open-enabled: true
    instances:
      user-service-cb:
        base-config: default
      order-service-cb:
        base-config: default

  timelimiter:
    configs:
      default:
        timeout-duration: 3s
    instances:
      user-service-tl:
        base-config: default

配置熔断过滤器路由:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service-circuit-breaker
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=2
            - name: CircuitBreaker
              args:
                name: user-service-cb
                fallbackUri: forward:/fallback/users

实现降级响应接口:

@RestController
public class FallbackController {

    @GetMapping("/fallback/users")
    public Mono<Map<String, Object>> userFallback() {
        return Mono.just(Map.of(
            "code", 503,
            "message", "用户服务暂时不可用,请稍后重试",
            "data", Collections.emptyList()
        ));
    }

    @GetMapping("/fallback/orders")
    public Mono<Map<String, Object>> orderFallback() {
        return Mono.just(Map.of(
            "code", 503,
            "message", "订单服务暂时不可用,请稍后重试",
            "data", Collections.emptyList()
        ));
    }
}

Gateway监控与健康检查

通过Actuator暴露Gateway的运行时指标和路由信息:

# application.yml
management:
  endpoints:
    web:
      exposure:
        include: gateway,health,metrics,prometheus
  endpoint:
    gateway:
      enabled: true
    health:
      show-details: always
# 查看所有路由配置
curl http://localhost:8080/actuator/gateway/routes

# 查看特定路由
curl http://localhost:8080/actuator/gateway/routes/user-service

# 查看全局过滤器
curl http://localhost:8080/actuator/gateway/globalfilters

# 查看路由过滤器工厂
curl http://localhost:8080/actuator/gateway/routefilters

# 动态刷新路由(添加路由)
curl -X POST http://localhost:8080/actuator/gateway/refresh

# 健康检查
curl http://localhost:8080/actuator/health

Spring Cloud Gateway作为微服务网关,通过Predicate断言匹配请求,Filter过滤器链处理请求和响应,配合Redis限流和Resilience4j熔断机制,构建了完整的API网关防护体系。在实际部署中,Gateway的响应式非阻塞模型在高并发请求转发场景下表现优异,Actuator端点提供了运行时路由管理和监控能力,支持动态刷新路由配置而无需重启服务。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springcloudgateway-wei-fu-wu-wang-guan-lu-you-guo-lyu-yu/

(0)
小编小编
上一篇 1小时前
下一篇 1小时前

相关推荐