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

Spring Cloud Gateway架构与路由模型设计

Spring Cloud Gateway是Spring官方推出的微服务API网关,基于Spring WebFlux和Project Reactor构建,提供非阻塞式的请求转发能力。在微服务架构中,网关承担统一入口的角色,所有外部请求经过网关进行路由转发、鉴权拦截、限流熔断和日志审计。相比传统的Zuul 1.x基于Servlet的阻塞模型,Spring Cloud Gateway的Reactor模型在高并发场景下吞吐量提升显著。

Gateway的核心模型由Route(路由)、Predicate(断言)和Filter(过滤器)三部分组成。Route是一条完整路由规则,包含目标URI、断言列表和过滤器列表。Predicate匹配请求条件(Path、Header、Method、Host等),Filter在请求前后执行增强逻辑(鉴权、日志、限流、重写)。

依赖配置与基础启动类:

<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-cloud-starter</artifactId>
</dependency>

// 启动类
@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

路由配置与动态路由实现

Gateway路由规则可以通过YAML配置文件或Java DSL定义。YAML方式适合静态路由,Java DSL适合需要动态更新的场景。

# application.yml - 静态路由配置
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
            - Method=GET,POST
          filters:
            - StripPrefix=2
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100
                redis-rate-limiter.burstCapacity: 200

        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
            - Header=X-Version, v2
          filters:
            - StripPrefix=2
            - AddResponseHeader=X-Gateway, cloud-gateway

lb://前缀表示使用负载均衡,Gateway通过Nacos或Eureka注册中心解析服务名并选择实例。StripPrefix=2表示去掉URL前两级路径前缀,例如/api/users/profile转发为/profile。

动态路由通过RouteLocator Bean实现,适合需要运行时更新的场景:

@Configuration
public class DynamicRouteConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("user-service", r -> r
                .path("/api/users/**")
                .filters(f -> f
                    .stripPrefix(2)
                    .filter((exchange, chain) -> {
                        ServerHttpRequest req = exchange.getRequest();
                        String token = req.getHeaders().getFirst("Authorization");
                        if (token == null || !token.startsWith("Bearer ")) {
                            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                            return exchange.getResponse().setComplete();
                        }
                        return chain.filter(exchange);
                    })
                )
                .uri("lb://user-service"))
            .build();
    }
}

限流过滤器与Redis令牌桶实现

RequestRateLimiter是Gateway内置的限流过滤器,基于Redis令牌桶算法实现。replenishRate是令牌填充速率(每秒令牌数),burstCapacity是桶容量(突发请求上限)。每个请求消耗一个令牌,令牌不足时返回429状态码。

spring:
  cloud:
    gateway:
      routes:
        - id: rate-limited-service
          uri: lb://payment-service
          predicates:
            - Path=/api/payment/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 50
                redis-rate-limiter.burstCapacity: 100
                key-resolver: "#{@userKeyResolver}"

@Component
public class UserKeyResolver implements KeyResolver {
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");
        return Mono.just(userId != null ? userId : "anonymous");
    }
}

key-resolver定义限流维度:基于用户ID、客户端IP或API路径进行差异化限流。上述配置按用户ID限流,每个用户每秒50个请求,突发上限100。

熔断降级与Resilience4j集成

Gateway 3.0后推荐使用Resilience4j替代Hystrix实现熔断降级。CircuitBreaker过滤器在下游服务异常时触发熔断,将请求路由到降级逻辑。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>

spring:
  cloud:
    gateway:
      routes:
        - id: circuit-breaker-route
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - name: CircuitBreaker
              args:
                name: orderServiceCB
                fallbackUri: forward:/fallback/orders

# Resilience4j配置
resilience4j:
  circuitbreaker:
    configs:
      default:
        failureRateThreshold: 50
        slowCallRateThreshold: 60
        slowCallDurationThreshold: 2s
        minimumNumberOfCalls: 10
        waitDurationInOpenState: 30s
        permittedNumberOfCallsInHalfOpenState: 5
        slidingWindowSize: 20
        slidingWindowType: COUNT_BASED

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

熔断器有三个状态:CLOSED(正常放行)、OPEN(熔断拒绝)、HALF_OPEN(半开探测)。当失败率超过failureRateThreshold(50%)时进入OPEN状态,等待waitDurationInOpenState后进入HALF_OPEN,放行5个探测请求,成功则恢复CLOSED,失败则回到OPEN。

全局过滤器与请求链路追踪

全局过滤器(GlobalFilter)对所有路由生效,适合实现鉴权、日志、链路追踪等横切逻辑。通过@Order注解控制过滤器执行顺序。

@Component
@Order(-100)
public class AuthGlobalFilter implements GlobalFilter {

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

        // 白名单路径跳过鉴权
        if (path.matches("/api/auth/(login|register)")) {
            return chain.filter(exchange);
        }

        String token = req.getHeaders().getFirst("Authorization");
        if (token == null) {
            return unauthorized(exchange, "Missing Authorization header");
        }

        try {
            Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token.replace("Bearer ", ""))
                .getBody();
            ServerHttpRequest mutated = req.mutate()
                .header("X-User-Id", claims.getSubject())
                .header("X-User-Role", claims.get("role", String.class))
                .build();
            return chain.filter(exchange.mutate().request(mutated).build());
        } catch (Exception e) {
            return unauthorized(exchange, "Invalid token");
        }
    }

    private Mono<Void> unauthorized(ServerWebExchange exchange, String msg) {
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        exchange.getResponse().getHeaders()
            .setContentType(MediaType.APPLICATION_JSON);
        String body = "{\"code\":401,\"message\":\"" + msg + "\"}";
        DataBuffer buffer = exchange.getResponse().bufferFactory()
            .wrap(body.getBytes(StandardCharsets.UTF_8));
        return exchange.getResponse().writeWith(Mono.just(buffer));
    }
}

在服务治理层面,Spring Cloud Gateway配合Nacos注册中心可以实现服务发现与配置中心一体化管理。Gateway自身也注册为Nacos服务实例,支持多实例集群部署。通过Nginx或SLB在Gateway前面做负载均衡,实现高可用网关集群。结合Sleuth+Zipkin或SkyWalking,可以在Gateway层注入TraceID,实现请求从网关到下游微服务的完整链路追踪。

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

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

相关推荐