找回密码
 立即注册
首页 业界区 业界 Spring Cloud Gateway 源码分析一

Spring Cloud Gateway 源码分析一

忌才砟 昨天 20:15
Spring Cloud Gateway 总体概述

请关注微信公众号:阿呆-bot
1. 项目概述

Spring Cloud Gateway 是 Spring 官方提供的 API 网关解决方案,基于 Spring Framework、Spring Boot 和 Project Reactor 构建。简单说,它就是微服务架构的"门卫",所有请求都要经过它,由它来决定请求应该转发到哪个服务。
为什么需要 Gateway?
想象一下,你的微服务架构有 10 个服务:

  • 用户服务(user-service)
  • 订单服务(order-service)
  • 商品服务(product-service)
  • 支付服务(payment-service)
  • ...等等
如果没有 Gateway,客户端需要知道每个服务的地址,而且每个服务都要单独处理认证、限流、监控等。有了 Gateway,客户端只需要知道 Gateway 的地址,Gateway 会负责:

  • 路由请求到正确的服务
  • 统一处理认证、授权
  • 统一处理限流、熔断
  • 统一处理监控、日志
1.1 核心特性

Gateway 提供了很多强大的功能,让我们一个个来看:

  • 动态路由: 支持配置文件和 API 动态配置路由
    1. # 配置文件方式
    2. spring:
    3.   cloud:
    4.     gateway:
    5.       routes:
    6.         - id: user-service
    7.           uri: http://localhost:8081
    复制代码
    1. // API 方式(动态添加路由)
    2. routeDefinitionRepository.save(routeDefinition);
    复制代码
  • 请求匹配: 支持路径、方法、请求头、主机等多种匹配方式
    1. predicates:
    2.   - Path=/api/users/**      # 路径匹配
    3.   - Method=GET              # 方法匹配
    4.   - Header=X-API-Key        # 请求头匹配
    5.   - Host=*.example.com      # 主机匹配
    复制代码
  • 过滤器链: 支持全局过滤器和路由过滤器
    1. // 全局过滤器(应用于所有路由)
    2. @Component
    3. public class AuthFilter implements GlobalFilter { ... }
    4. // 路由过滤器(只应用于特定路由)
    5. filters:
    6.   - AddRequestHeader=X-User-Id, 123
    复制代码
  • 服务发现: 集成 Spring Cloud DiscoveryClient(Eureka、Consul 等)
    1. # 自动从服务注册中心发现服务
    2. spring:
    3.   cloud:
    4.     gateway:
    5.       discovery:
    6.         locator:
    7.           enabled: true
    复制代码
  • 负载均衡: 集成 Spring Cloud LoadBalancer
    1. # 使用负载均衡
    2. uri: lb://user-service  # lb 表示负载均衡
    复制代码
  • 断路器: 集成 Spring Cloud Circuit Breaker
    1. filters:
    2.   - name: CircuitBreaker
    3.     args:
    4.       name: user-service
    5.       fallbackUri: forward:/fallback
    复制代码
  • 限流: 支持基于 Bucket4j 和 Redis 的限流
    1. filters:
    2.   - name: RequestRateLimiter
    3.     args:
    4.       redis-rate-limiter.replenishRate: 10
    5.       redis-rate-limiter.burstCapacity: 20
    复制代码
  • 多协议: 支持 HTTP/1.1、HTTP/2、WebSocket、gRPC
    1. // WebSocket 支持
    2. @Bean
    3. public RouterFunction<ServerResponse> websocketRoute() {
    4.     return RouterFunctions.route()
    5.         .GET("/ws", websocketHandler)
    6.         .build();
    7. }
    复制代码
2. 主要目录结构

2.1 核心模块
  1. spring-cloud-gateway/
  2. ├── spring-cloud-gateway-server-webflux/     # WebFlux 响应式实现
  3. │   ├── config/                              # 自动配置类
  4. │   ├── handler/                              # 请求处理器
  5. │   ├── filter/                               # 过滤器实现
  6. │   ├── route/                                # 路由相关
  7. │   └── support/                              # 工具类
  8. ├── spring-cloud-gateway-server-webmvc/     # WebMVC 传统实现
  9. │   ├── config/                              # 自动配置类
  10. │   ├── handler/                              # 请求处理器
  11. │   ├── filter/                               # 过滤器实现
  12. │   ├── predicate/                            # 谓词实现
  13. │   └── common/                               # 通用工具类
  14. ├── spring-cloud-gateway-proxyexchange-webflux/  # WebFlux 代理交换
  15. ├── spring-cloud-gateway-proxyexchange-webmvc/   # WebMVC 代理交换
  16. ├── spring-cloud-gateway-dependencies/       # 依赖管理
  17. ├── spring-cloud-gateway-sample/            # 示例应用
  18. └── spring-cloud-gateway-integration-tests/  # 集成测试
复制代码
2.2 关键目录说明

spring-cloud-gateway-server-webflux

WebFlux 模式的核心实现:

  • config/: 包含 GatewayAutoConfiguration 等自动配置类
  • handler/: 包含 FilteringWebHandler、RoutePredicateHandlerMapping 等处理器
  • filter/: 包含各种全局过滤器和过滤器工厂
  • route/: 包含路由定义、路由定位器等
spring-cloud-gateway-server-webmvc

WebMVC 模式的核心实现:

  • config/: 包含 GatewayServerMvcAutoConfiguration 等自动配置类
  • handler/: 包含 ProxyExchangeHandlerFunction 等处理器
  • filter/: 包含各种过滤器实现
  • predicate/: 包含路由谓词实现
3. Gateway 关键用法和示例

3.1 基本配置

使用 WebFlux 模式

WebFlux 模式适合高并发场景,性能优秀。配置起来也很简单:
Maven 依赖:
  1. <dependency>
  2.     <groupId>org.springframework.cloud</groupId>
  3.     spring-cloud-starter-gateway-server-webflux</artifactId>
  4. </dependency>
复制代码
application.yml 配置:
  1. spring:
  2.   cloud:
  3.     gateway:
  4.       server:
  5.         webflux:
  6.           enabled: true  # 启用 Gateway WebFlux 模式
  7.           routes:
  8.             - id: user-service
  9.               uri: lb://user-service  # lb 表示负载均衡
  10.               predicates:
  11.                 - Path=/api/users/**  # 路径匹配
  12.               filters:
  13.                 - StripPrefix=2  # 去掉前两个路径段
复制代码
配置说明

  • id: 路由的唯一标识,可以随便起名字
  • uri: 目标服务的地址,lb:// 表示使用负载均衡
  • predicates: 路由匹配条件,这里匹配 /api/users/** 路径
  • filters: 过滤器,StripPrefix=2 表示去掉 /api/users,只保留后面的路径
实际例子
  1. 客户端请求:GET /api/users/123
  2. 匹配路由:user-service
  3. 应用过滤器:StripPrefix=2
  4. 转发到:http://user-service/123  # 去掉了 /api/users
复制代码
使用 WebMVC 模式

WebMVC 模式适合传统 Spring MVC 应用,配置方式略有不同:
Maven 依赖:
  1. <dependency>
  2.     <groupId>org.springframework.cloud</groupId>
  3.     spring-cloud-starter-gateway-server-webmvc</artifactId>
  4. </dependency>
复制代码
application.yml 配置:
  1. spring:
  2.   cloud:
  3.     gateway:
  4.       server:
  5.         mvc:
  6.           enabled: true  # 启用 Gateway WebMVC 模式
  7.           routes:
  8.             - id: user-service
  9.               uri: http://localhost:8081  # 直接指定地址
  10.               predicates:
  11.                 - path=/api/users/**  # 注意:小写 path
  12.               filters:
  13.                 - strip-prefix=2  # 注意:小写 strip-prefix
复制代码
配置差异

  • WebFlux 使用 Path(大写),WebMVC 使用 path(小写)
  • WebFlux 使用 StripPrefix,WebMVC 使用 strip-prefix
  • WebMVC 不支持 lb:// 负载均衡,需要直接指定地址或使用服务发现
3.2 路由配置示例

路径重写

路径重写是 Gateway 的常用功能,可以修改请求路径再转发给下游服务。
配置示例
  1. spring:
  2.   cloud:
  3.     gateway:
  4.       routes:
  5.         - id: rewrite-route
  6.           uri: http://backend-service
  7.           predicates:
  8.             - Path=/api/**
  9.           filters:
  10.             - RewritePath=/api/(?<segment>.*), /$\{segment}
复制代码
实际例子
  1. 客户端请求:GET /api/users/123
  2. 匹配路径:/api/**
  3. 应用重写规则:/api/(?<segment>.*) -> /${segment}
  4. 重写后路径:/users/123
  5. 转发到:http://backend-service/users/123
复制代码
正则表达式说明

  • /api/(?.*): 匹配 /api/ 后面的所有内容,捕获到 segment 组
  • /${segment}: 使用捕获的 segment 组替换路径
  • 结果:/api/users/123 -> /users/123
更多例子
  1. # 去掉版本号
  2. - RewritePath=/api/v1/(?<segment>.*), /api/$\{segment}
  3. # /api/v1/users/123 -> /api/users/123
  4. # 添加前缀
  5. - RewritePath=/(?<segment>.*), /internal/$\{segment}
  6. # /users/123 -> /internal/users/123
复制代码
请求头添加

添加请求头和响应头是 Gateway 的常见需求,可以传递上下文信息。
配置示例
  1. spring:
  2.   cloud:
  3.     gateway:
  4.       routes:
  5.         - id: add-header-route
  6.           uri: http://backend-service
  7.           predicates:
  8.             - Path=/api/**
  9.           filters:
  10.             - AddRequestHeader=X-Request-Id, ${random.uuid}
  11.             - AddResponseHeader=X-Response-Time, ${T(java.lang.System).currentTimeMillis()}
复制代码
实际例子
  1. 客户端请求:
  2. GET /api/users/123
  3. Headers: Authorization: Bearer token123
  4. Gateway 转发给下游服务:
  5. GET /api/users/123
  6. Headers:
  7.   Authorization: Bearer token123  # 保留原始头
  8.   X-Request-Id: 550e8400-e29b-41d4-a716-446655440000  # 添加的新头
  9. 下游服务响应:
  10. 200 OK
  11. Headers: Content-Type: application/json
  12. Gateway 返回给客户端:
  13. 200 OK
  14. Headers:
  15.   Content-Type: application/json  # 保留原始头
  16.   X-Response-Time: 1699123456789  # 添加的新头
复制代码
常用场景

  • 请求追踪:添加 X-Request-Id,方便追踪请求链路
  • 用户信息:添加 X-User-Id,下游服务可以获取用户信息
  • 性能监控:添加 X-Response-Time,记录响应时间
  • API 版本:添加 X-API-Version,支持 API 版本控制
限流配置

限流是保护下游服务的重要手段,防止被大量请求压垮。
配置示例
  1. spring:
  2.   cloud:
  3.     gateway:
  4.       routes:
  5.         - id: rate-limit-route
  6.           uri: http://backend-service
  7.           predicates:
  8.             - Path=/api/**
  9.           filters:
  10.             - name: RequestRateLimiter
  11.               args:
  12.                 redis-rate-limiter.replenishRate: 10  # 每秒补充 10 个令牌
  13.                 redis-rate-limiter.burstCapacity: 20  # 突发容量 20 个令牌
复制代码
工作原理
  1. 令牌桶算法:
  2. - 每秒补充 10 个令牌(replenishRate)
  3. - 桶容量 20 个令牌(burstCapacity)
  4. - 每个请求消耗 1 个令牌
  5. 场景1:正常请求
  6. - 每秒 10 个请求:正常通过 ✓
  7. - 突发 20 个请求:前 20 个通过,后面的等待
  8. 场景2:超过限流
  9. - 每秒 15 个请求:前 10 个通过,后 5 个被限流 ✗
  10. - 返回 429 Too Many Requests
复制代码
实际例子
  1. // 限流配置
  2. replenishRate: 10  // 每秒 10 个请求
  3. burstCapacity: 20  // 突发最多 20 个请求
  4. // 请求场景
  5. 第 1 秒:15 个请求
  6.   - 前 10 个:通过(使用补充的令牌)
  7.   - 后 5 个:通过(使用突发容量)
  8.   
  9. 第 2 秒:25 个请求
  10.   - 前 10 个:通过(使用补充的令牌)
  11.   - 中间 10 个:通过(使用突发容量,桶里还有 10 个)
  12.   - 后 5 个:被限流(返回 429)
  13. 第 3 秒:5 个请求
  14.   - 全部通过(桶里补充了 10 个令牌)
复制代码
自定义限流键
  1. // 可以根据用户 ID 限流
  2. @Bean
  3. public KeyResolver userKeyResolver() {
  4.     return exchange -> {
  5.         String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");
  6.         return Mono.just(userId != null ? userId : "anonymous");
  7.     };
  8. }
复制代码
3.3 编程式路由配置

WebFlux 模式
  1. @Configuration
  2. public class GatewayConfig {
  3.    
  4.     @Bean
  5.     public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
  6.         return builder.routes()
  7.             .route("custom-route", r -> r
  8.                 .path("/api/custom/**")
  9.                 .uri("http://custom-service"))
  10.             .build();
  11.     }
  12. }
复制代码
WebMVC 模式
  1. @Configuration
  2. public class GatewayMvcConfig {
  3.    
  4.     @Bean
  5.     public RouterFunction<ServerResponse> customRouter() {
  6.         return GatewayRouterFunctions.route("custom-route")
  7.             .GET("/api/custom/**", HandlerFunctions.http())
  8.             .build();
  9.     }
  10. }
复制代码
3.4 自定义过滤器

WebFlux 全局过滤器
  1. @Component
  2. public class CustomGlobalFilter implements GlobalFilter, Ordered {
  3.    
  4.     @Override
  5.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  6.         // 前置处理
  7.         ServerHttpRequest request = exchange.getRequest();
  8.         String requestId = UUID.randomUUID().toString();
  9.         
  10.         // 添加请求头
  11.         ServerHttpRequest modifiedRequest = request.mutate()
  12.             .header("X-Request-Id", requestId)
  13.             .build();
  14.         
  15.         return chain.filter(exchange.mutate().request(modifiedRequest).build())
  16.             .then(Mono.fromRunnable(() -> {
  17.                 // 后置处理
  18.                 log.info("Request processed: {}", requestId);
  19.             }));
  20.     }
  21.    
  22.     @Override
  23.     public int getOrder() {
  24.         return -1; // 高优先级
  25.     }
  26. }
复制代码
WebMVC 过滤器
  1. @Component
  2. public class CustomFilterFunction implements FilterFunction {
  3.    
  4.     @Override
  5.     public ServerRequest filter(ServerRequest request) {
  6.         // 处理请求
  7.         return ServerRequest.from(request)
  8.             .header("X-Request-Id", UUID.randomUUID().toString())
  9.             .build();
  10.     }
  11.    
  12.     @Override
  13.     public ServerResponse filter(ServerRequest request, ServerResponse response) {
  14.         // 处理响应
  15.         return ServerResponse.from(response)
  16.             .header("X-Response-Time", String.valueOf(System.currentTimeMillis()))
  17.             .build();
  18.     }
  19. }
复制代码
4. 应用场景

4.1 微服务网关

这是 Gateway 最常见的应用场景。作为微服务架构的统一入口,Gateway 可以:
实际例子
  1. 微服务架构:
  2. - 用户服务(user-service:8081)
  3. - 订单服务(order-service:8082)
  4. - 商品服务(product-service:8083)
  5. - 支付服务(payment-service:8084)
  6. 客户端只需要知道 Gateway 的地址(gateway:8080)
  7. Gateway 配置:
  8. spring:
  9.   cloud:
  10.     gateway:
  11.       routes:
  12.         - id: user-service
  13.           uri: http://user-service:8081
  14.           predicates:
  15.             - Path=/api/users/**
  16.         - id: order-service
  17.           uri: http://order-service:8082
  18.           predicates:
  19.             - Path=/api/orders/**
复制代码
统一处理横切关注点

  • 认证、授权:在 Gateway 统一处理,下游服务不需要关心
    1. @Component
    2. public class AuthFilter implements GlobalFilter {
    3.     @Override
    4.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    5.         String token = exchange.getRequest().getHeaders().getFirst("Authorization");
    6.         if (!isValid(token)) {
    7.             exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
    8.             return exchange.getResponse().setComplete();
    9.         }
    10.         return chain.filter(exchange);
    11.     }
    12. }
    复制代码
  • 监控、日志:统一收集所有请求的指标和日志
    1. @Component
    2. public class LoggingFilter implements GlobalFilter {
    3.     @Override
    4.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    5.         long startTime = System.currentTimeMillis();
    6.         return chain.filter(exchange).then(Mono.fromRunnable(() -> {
    7.             long duration = System.currentTimeMillis() - startTime;
    8.             log.info("Request: {} {} - Duration: {}ms",
    9.                 exchange.getRequest().getMethod(),
    10.                 exchange.getRequest().getPath(),
    11.                 duration);
    12.         }));
    13.     }
    14. }
    复制代码
  • 限流、熔断:保护下游服务,防止被压垮
    1. filters:
    2.   - name: RequestRateLimiter
    3.     args:
    4.       redis-rate-limiter.replenishRate: 10
    5.   - name: CircuitBreaker
    6.     args:
    7.       name: user-service
    8.       fallbackUri: forward:/fallback
    复制代码
4.2 API 聚合

Gateway 可以聚合多个后端服务的 API,减少客户端请求次数。
实际例子
  1. 客户端需要获取用户订单详情,需要调用:
  2. 1. GET /api/users/123  # 获取用户信息
  3. 2. GET /api/orders/456  # 获取订单信息
  4. 3. GET /api/products/789  # 获取商品信息
  5. 如果没有 Gateway,客户端需要发起 3 次请求。
  6. 有了 Gateway,可以创建一个聚合接口:
  7. GET /api/user-order-detail?userId=123&orderId=456
  8. Gateway 聚合逻辑:
  9. @Component
  10. public class AggregateFilter implements GlobalFilter {
  11.     @Override
  12.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  13.         if (exchange.getRequest().getPath().value().equals("/api/user-order-detail")) {
  14.             // 并行调用多个服务
  15.             Mono<User> user = getUserService(exchange);
  16.             Mono<Order> order = getOrderService(exchange);
  17.             Mono<Product> product = getProductService(exchange);
  18.             
  19.             return Mono.zip(user, order, product)
  20.                 .map(tuple -> {
  21.                     // 聚合结果
  22.                     return new UserOrderDetail(tuple.getT1(), tuple.getT2(), tuple.getT3());
  23.                 })
  24.                 .flatMap(result -> {
  25.                     // 返回聚合结果
  26.                     return writeResponse(exchange, result);
  27.                 });
  28.         }
  29.         return chain.filter(exchange);
  30.     }
  31. }
复制代码
优势

  • 减少客户端请求次数(3 次 -> 1 次)
  • 减少网络延迟
  • 提供统一的 API 接口
4.3 请求转换

Gateway 可以在转发请求时进行各种转换。
协议转换
  1. // HTTP 到 gRPC 转换
  2. @Component
  3. public class GrpcFilter implements GlobalFilter {
  4.     @Override
  5.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  6.         if (exchange.getRequest().getPath().value().startsWith("/grpc/")) {
  7.             // 将 HTTP 请求转换为 gRPC 请求
  8.             return convertToGrpc(exchange)
  9.                 .flatMap(grpcRequest -> {
  10.                     // 调用 gRPC 服务
  11.                     return callGrpcService(grpcRequest);
  12.                 });
  13.         }
  14.         return chain.filter(exchange);
  15.     }
  16. }
复制代码
数据格式转换
  1. // JSON 到 XML 转换
  2. @Component
  3. public class FormatConverterFilter implements GlobalFilter {
  4.     @Override
  5.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  6.         String accept = exchange.getRequest().getHeaders().getFirst("Accept");
  7.         if ("application/xml".equals(accept)) {
  8.             // 将 JSON 响应转换为 XML
  9.             return chain.filter(exchange)
  10.                 .then(Mono.fromRunnable(() -> {
  11.                     String json = getResponseBody(exchange);
  12.                     String xml = convertJsonToXml(json);
  13.                     setResponseBody(exchange, xml);
  14.                 }));
  15.         }
  16.         return chain.filter(exchange);
  17.     }
  18. }
复制代码
路径重写
  1. # 版本号处理
  2. filters:
  3.   - RewritePath=/api/v1/(?<segment>.*), /api/$\{segment}
  4. # /api/v1/users/123 -> /api/users/123
复制代码
4.4 安全控制

Gateway 可以作为安全的第一道防线。
API 认证和授权
  1. @Component
  2. public class SecurityFilter implements GlobalFilter {
  3.     @Override
  4.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  5.         String token = exchange.getRequest().getHeaders().getFirst("Authorization");
  6.         
  7.         // 验证 Token
  8.         if (!isValidToken(token)) {
  9.             exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
  10.             return exchange.getResponse().setComplete();
  11.         }
  12.         
  13.         // 检查权限
  14.         if (!hasPermission(token, exchange.getRequest().getPath().value())) {
  15.             exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
  16.             return exchange.getResponse().setComplete();
  17.         }
  18.         
  19.         return chain.filter(exchange);
  20.     }
  21. }
复制代码
IP 白名单/黑名单
  1. @Component
  2. public class IpFilter implements GlobalFilter {
  3.     private final Set<String> whitelist = Set.of("192.168.1.100", "10.0.0.1");
  4.     private final Set<String> blacklist = Set.of("192.168.1.200");
  5.    
  6.     @Override
  7.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  8.         String clientIp = getClientIp(exchange);
  9.         
  10.         // 检查黑名单
  11.         if (blacklist.contains(clientIp)) {
  12.             exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
  13.             return exchange.getResponse().setComplete();
  14.         }
  15.         
  16.         // 检查白名单(如果配置了)
  17.         if (!whitelist.isEmpty() && !whitelist.contains(clientIp)) {
  18.             exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
  19.             return exchange.getResponse().setComplete();
  20.         }
  21.         
  22.         return chain.filter(exchange);
  23.     }
  24. }
复制代码
防止攻击
  1. // 防止 SQL 注入、XSS 攻击
  2. @Component
  3. public class SecurityFilter implements GlobalFilter {
  4.     @Override
  5.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  6.         String query = exchange.getRequest().getURI().getQuery();
  7.         
  8.         // 检查 SQL 注入
  9.         if (containsSqlInjection(query)) {
  10.             exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
  11.             return exchange.getResponse().setComplete();
  12.         }
  13.         
  14.         // 检查 XSS
  15.         if (containsXss(query)) {
  16.             exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
  17.             return exchange.getResponse().setComplete();
  18.         }
  19.         
  20.         return chain.filter(exchange);
  21.     }
  22. }
复制代码
4.5 监控和可观测性

Gateway 可以统一收集监控数据,方便排查问题。
请求指标收集
  1. @Component
  2. public class MetricsFilter implements GlobalFilter {
  3.     private final MeterRegistry meterRegistry;
  4.    
  5.     @Override
  6.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  7.         long startTime = System.currentTimeMillis();
  8.         String routeId = exchange.getAttribute(GATEWAY_ROUTE_ATTR).getId();
  9.         
  10.         return chain.filter(exchange).then(Mono.fromRunnable(() -> {
  11.             long duration = System.currentTimeMillis() - startTime;
  12.             
  13.             // 记录指标
  14.             meterRegistry.counter("gateway.requests", "route", routeId).increment();
  15.             meterRegistry.timer("gateway.duration", "route", routeId).record(duration, TimeUnit.MILLISECONDS);
  16.         }));
  17.     }
  18. }
复制代码
分布式追踪
  1. // 集成 Zipkin/Sleuth
  2. @Component
  3. public class TracingFilter implements GlobalFilter {
  4.     @Override
  5.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  6.         // 创建追踪 Span
  7.         Span span = tracer.nextSpan().name("gateway-request").start();
  8.         
  9.         try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) {
  10.             // 添加追踪信息到请求头
  11.             exchange.getRequest().mutate()
  12.                 .header("X-Trace-Id", span.context().traceId())
  13.                 .header("X-Span-Id", span.context().spanId())
  14.                 .build();
  15.             
  16.             return chain.filter(exchange)
  17.                 .doFinally(signalType -> span.end());
  18.         }
  19.     }
  20. }
复制代码
性能监控
  1. // 监控响应时间、错误率等
  2. @Component
  3. public class PerformanceFilter implements GlobalFilter {
  4.     @Override
  5.     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  6.         long startTime = System.currentTimeMillis();
  7.         
  8.         return chain.filter(exchange)
  9.             .doOnSuccess(v -> {
  10.                 long duration = System.currentTimeMillis() - startTime;
  11.                 // 记录成功请求的响应时间
  12.                 recordSuccess(duration);
  13.             })
  14.             .doOnError(throwable -> {
  15.                 // 记录错误
  16.                 recordError(throwable);
  17.             });
  18.     }
  19. }
复制代码
5. 优缺点总结

5.1 优点 ✅


  • 功能丰富

    • 支持多种路由匹配方式
    • 丰富的过滤器生态
    • 集成 Spring Cloud 生态

  • 灵活配置

    • 支持配置文件配置
    • 支持编程式配置
    • 支持动态路由

  • 性能优秀(WebFlux 模式)

    • 非阻塞 I/O
    • 高并发支持
    • 资源利用率高

  • 易于集成

    • 与 Spring Boot 无缝集成
    • 支持服务发现
    • 支持负载均衡

  • 可扩展性强

    • 支持自定义过滤器
    • 支持自定义谓词
    • 插件化架构

6. 最佳实践

6.1 路由设计


  • 使用有意义的路由 ID
    1. routes:
    2.   - id: user-service-route  # 清晰的路由 ID
    复制代码
  • 合理使用路径匹配
    1. predicates:
    2.   - Path=/api/v1/users/**  # 使用版本化路径
    复制代码
  • 避免过于复杂的路由规则

    • 保持路由规则简单清晰
    • 避免深层嵌套的路径匹配

6.2 过滤器使用


  • 合理设置过滤器顺序
    1. @Override
    2. public int getOrder() {
    3.     return Ordered.HIGHEST_PRECEDENCE;  // 高优先级
    4. }
    复制代码
  • 避免阻塞操作(WebFlux)
    1. // ❌ 错误:阻塞操作
    2. String result = blockingService.call();
    3. // ✅ 正确:非阻塞操作
    4. return Mono.fromCallable(() -> blockingService.call())
    5.     .subscribeOn(Schedulers.boundedElastic());
    复制代码
  • 合理使用全局过滤器

    • 全局过滤器应用于所有路由
    • 路由过滤器只应用于特定路由

6.3 性能优化


  • 启用路由过滤器缓存(WebFlux)
    1. spring:
    2.   cloud:
    3.     gateway:
    4.       server:
    5.         webflux:
    6.           route-filter-cache-enabled: true
    复制代码
  • 合理配置线程池(WebMVC)
    1. server:
    2.   tomcat:
    3.     threads:
    4.       max: 200
    5.       min-spare: 10
    复制代码
  • 使用连接池
    1. spring:
    2.   cloud:
    3.     gateway:
    4.       httpclient:
    5.         pool:
    6.           max-connections: 500
    复制代码
6.4 监控和可观测性


  • 启用 Actuator
    1. management:
    2.   endpoints:
    3.     web:
    4.       exposure:
    5.         include: gateway,health,metrics
    复制代码
  • 集成分布式追踪
    1. spring:
    2.   sleuth:
    3.     zipkin:
    4.       base-url: http://zipkin:9411
    复制代码
  • 监控关键指标

    • 请求数量
    • 响应时间
    • 错误率
    • 路由匹配率

7. 总结

Spring Cloud Gateway 是一个功能强大、灵活的 API 网关解决方案,提供了 WebMVC 和 WebFlux 两种实现模式,可以满足不同场景的需求。
选择建议

  • 高并发场景: 选择 WebFlux 模式
  • 传统应用: 选择 WebMVC 模式
  • 微服务网关: 优先选择 WebFlux 模式
  • 快速开发: 选择 WebMVC 模式
关键要点

  • 理解两种模式的差异和适用场景
  • 合理设计路由规则
  • 正确使用过滤器
  • 关注性能和监控
  • 遵循最佳实践

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册