一文搞定!Gateway 集成 Spring Boot 核心场景:路由配置、动态发现与性能调优 高频面试题全解析(附代码示例)

1,033 阅读15分钟

Gateway 网关:从入门到实战

d0f99d4a-75bb-4b5c-b29c-72a9bc3277a6_1747539770525618310_origin~tplv-a9rns2rl98-image-qvalue.jpeg

一、整合前提

  1. 技术栈版本匹配

    • Spring Boot:建议 2.3.x 及以上(Gateway 基于 Spring Boot 2.x 开发)。

    • Spring Cloud:需与 Spring Boot 版本兼容,例如:

      • Spring Boot 2.7.x → Spring Cloud 2021.0.x(如 spring-cloud-starter-gateway)。
      • Spring Boot 3.x → Spring Cloud 2022.0.x(需适配 WebFlux 响应式编程模型)。
  2. 核心依赖

    <!-- Spring Cloud Gateway 核心依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    
    <!-- 可选:集成注册中心(如 Nacos/Eureka) -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
    <!-- 可选:流量控制与熔断(如 Sentinel) -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    

二、快速入门:搭建基础网关

1. 创建 Spring Boot 项目

通过 Spring Initializr 初始化项目,勾选:

  • Spring Webflux(非 WebMvc,Gateway 基于响应式编程)。
  • Spring Cloud Gateway 依赖。
2. 配置文件(application.yml)
server:
  port: 8080 # 网关端口

spring:
  application:
    name: gateway-server # 服务名
  cloud:
    gateway:
      routes: # 路由配置
        - id: example-route # 路由 ID(唯一)
          uri: http://localhost:8081 # 目标服务地址(可替换为 lb://service-name 实现负载均衡)
          predicates: # 路由断言(匹配请求条件)
            - Path=/api/** # 匹配以 /api/ 开头的路径
          filters: # 路由过滤器(请求/响应处理)
            - StripPrefix=1 # 去除路径前缀(如 /api/user → /user)
            - AddRequestHeader=X-From-Gateway, true # 添加请求头
3. 启动类(无需特殊配置)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}
4. 验证路由

启动网关后,访问 http://localhost:8080/api/hello,请求会被转发到 http://localhost:8081/hello,并携带自定义请求头 X-From-Gateway: true

三、核心功能整合实战

1. 动态路由(集成 Nacos 注册中心)
步骤 1:添加 Nacos 依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
步骤 2:配置 Nacos 注册中心
spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # Nacos 地址
    gateway:
      discovery:
        locator:
          enabled: true # 启用服务发现路由
          lower-case-service-id: true # 路由 ID 小写(默认驼峰)
      routes:
        - id: user-service # 服务名(需与 Nacos 注册的服务名一致)
          uri: lb://user-service # lb 表示负载均衡
          predicates:
            - Path=/user/**
原理
  • 网关从 Nacos 获取服务实例列表,通过 lb:// 前缀实现负载均衡。
  • 动态更新:修改 Nacos 服务实例,网关自动刷新路由(需配置 spring.cloud.gateway.discovery.locator.enabled=true)。
2. 流量控制(集成 Sentinel)
步骤 1:添加 Sentinel 依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
步骤 2:配置 Sentinel 控制台
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 # Sentinel 控制台地址(需提前启动)
        port: 8719 # 通信端口
      eager: true # 提前初始化 Sentinel
    gateway:
      datasource:
        flow: # 限流规则数据源
          nacos:
            server-addr: localhost:8848
            data-id: gateway-flow-rules # Nacos 中存储的规则文件
            group-id: DEFAULT_GROUP
            data-type: json
步骤 3:定义限流规则(Nacos 配置)
[
  {
    "resource": "/user/**", // 资源名(路由路径或服务名)
    "limitApp": "default", // 应用来源
    "grade": 1, // 限流模式(1=QPS,0=线程数)
    "count": 100, // 阈值(QPS 100)
    "intervalSec": 1 // 统计窗口(秒)
  }
]
效果

当 /user/** 接口的 QPS 超过 100 时,Sentinel 会拦截请求并返回限流提示。

3. 权限认证(JWT 全局过滤器)
步骤 1:自定义全局过滤器
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class JwtAuthFilter implements GlobalFilter, Ordered {
    private static final String JWT_TOKEN_HEADER = "Authorization";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 从请求头获取 JWT 令牌
        String token = exchange.getRequest().getHeaders().getFirst(JWT_TOKEN_HEADER);
        
        if (token == null || !token.startsWith("Bearer ")) {
            // 无令牌或格式错误,返回 401 未认证
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        // 验证令牌逻辑(此处简化,实际需对接认证中心)
        boolean isValid = validateToken(token.split(" ")[1]);
        if (!isValid) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        // 令牌有效,放行请求
        return chain.filter(exchange);
    }

    private boolean validateToken(String token) {
        // 调用 JWT 解析库验证(如 jjwt)
        return true;
    }

    @Override
    public int getOrder() {
        return -100; // 优先级:数值越小,执行越早
    }
}
步骤 2:配置跨域(CORS)
spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]': # 匹配所有路径
            allowedOrigins: "*"
            allowedMethods: "*"
            allowedHeaders: "*"
            allowCredentials: true

四、高级场景:整合 Spring Boot 微服务

假设已有两个 Spring Boot 微服务:

  • 用户服务(user-service) :端口 8081,路径 /user/{id}
  • 商品服务(product-service) :端口 8082,路径 /product/{id}
1. 网关路由配置
spring:
  cloud:
    gateway:
      routes:
        - id: user-service-route
          uri: http://localhost:8081 # 直接路由(非负载均衡)
          predicates:
            - Path=/api/user/**
          filters:
            - StripPrefix=1 # 去除 /api 前缀,转发至 /user/**

        - id: product-service-route
          uri: lb://product-service # 动态路由(需注册到 Nacos)
          predicates:
            - Path=/api/product/**
          filters:
            - StripPrefix=1
2. 微服务注册到 Nacos

在微服务的 application.yml 中配置:

spring:
  application:
    name: product-service # 服务名(需与网关路由中的 lb:// 一致)
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # Nacos 地址

五、常见问题与解决方案

1. 跨域问题(No 'Access-Control-Allow-Origin' header)
  • 原因:未配置 CORS 规则。

  • 解决

    • 添加全局 CORS 配置(见上文权限认证部分)。
    • 确保 allowedOrigins 匹配前端域名,避免使用 * 时携带凭证(需设置 allowCredentials: true 并指定具体域名)。
2. 路由不生效
  • 排查步骤

    1. 检查网关日志,确认请求是否匹配到路由(开启调试日志:logging.level.org.springframework.cloud.gateway=DEBUG)。
    2. 验证 predicates 配置是否正确(如路径匹配是否包含 /)。
    3. 若使用动态路由,确认服务已注册到注册中心,且 uri 格式为 lb://service-name
3. 响应体中文乱码
  • 原因:网关默认字符集为 ISO-8859-1。

  • 解决:在过滤器中设置响应编码:

    exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
    
4. 阻塞操作导致性能下降
  • 原因:在过滤器中使用同步阻塞 API(如传统 JDBC 操作)。

  • 解决

    • 改用响应式组件(如 R2DBC)。

    • 将阻塞操作提交到自定义线程池:

      import reactor.core.scheduler.Schedulers;
      
      Mono.fromCallable(() -> blockingOperation())
          .subscribeOn(Schedulers.boundedElastic())
          .flatMap(result -> chain.filter(exchange));
      

六、性能优化建议

  1. 线程池配置

    spring:
      cloud:
        gateway:
          threads:
            worker:
              core-size: 20 # 核心线程数(建议为 CPU 核心数 2-4 倍)
              max-size: 100 # 最大线程数
    
  2. 响应压缩

    spring:
      cloud:
        gateway:
          httpclient:
            response-timeout: 5s # 超时时间
            compression:
              enabled: true # 启用 gzip 压缩
              mime-types: text/html,text/css,application/json # 压缩类型
    
  3. 缓存静态资源
    使用 CacheResponseFilter 或集成 Redis 缓存高频请求结果:

    filters:
      - CacheResponse=3600 # 缓存响应 1 小时
    

七、Gateway 常见面试题

1. 什么是 Spring Cloud Gateway?它的核心功能有哪些?

参考答案
Spring Cloud Gateway 是 Spring 官方基于 WebFlux 框架开发的 API 网关,作为微服务架构的统一入口,负责请求路由、过滤、负载均衡等功能。其核心功能包括:

  • 路由转发:根据断言(Predicate)匹配请求,将其转发到目标服务。
  • 过滤器链:支持全局过滤器(GlobalFilter)和局部过滤器(GatewayFilter),用于请求 / 响应增强(如参数校验、权限认证、日志记录)。
  • 熔断降级:集成 Sentinel 或 Resilience4j 实现服务熔断和流量控制。
  • 负载均衡:与注册中心(如 Nacos、Eureka)结合,实现动态服务发现和请求分发。
  • 安全增强:集成 OAuth2、JWT 等认证机制,防范 SQL 注入、XSS 攻击。

2. Spring Cloud Gateway 与 Zuul 的区别是什么?

参考答案

对比项Spring Cloud GatewayZuul
底层框架基于 Spring WebFlux(Reactor 模型)基于 Servlet API(阻塞式 IO)
响应式支持支持非阻塞、异步请求处理仅支持同步处理
性能高并发场景下吞吐量更高传统 Servlet 模型,性能较低
过滤器模型基于 WebFilter 链基于 Servlet Filter 链
集成度与 Spring 生态无缝集成需额外配置整合 Spring 组件
版本维护官方主推网关,持续更新Zuul 1.x 停止维护,Zuul 2.x 重构

3. 如何配置 Spring Cloud Gateway 的路由规则?有哪些断言(Predicate)可用?

参考答案
路由规则可通过配置文件(如 YAML)或 Java 代码定义,核心元素包括:

  • id:路由唯一标识

  • uri:目标服务地址(支持lb://负载均衡前缀)

  • predicates:匹配条件(如 Path、Method、Header 等)

  • filters:过滤器链

示例配置

spring:
  cloud:
    gateway:
      routes:
        - id: user-service-route
          uri: lb://user-service
          predicates:
            - Path=/users/**
            - Method=GET,POST
          filters:
            - StripPrefix=1

常见断言类型

  • Path:路径匹配(如/api/**
  • Method:HTTP 方法匹配(GET/POST)
  • Header:请求头匹配(如X-Request-Id
  • Query:查询参数匹配(如param=value
  • Cookie/Host/RemoteAddr等。

4. 如何实现自定义过滤器?GlobalFilter 和 GatewayFilter 的区别是什么?

参考答案
自定义过滤器实现方式

  1. GlobalFilter(全局过滤器):实现GlobalFilterOrdered接口,作用于所有路由。

    @Component
    public class AuthFilter implements GlobalFilter, Ordered {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 认证逻辑
            return chain.filter(exchange);
        }
        @Override
        public int getOrder() { return -100; } // 优先级
    }
    
  2. GatewayFilter(局部过滤器):通过@Bean定义或配置文件声明,仅作用于指定路由。

    filters:
      - AddRequestHeader=X-Request-Foo, Bar
    

核心区别

类型作用范围实现方式应用场景
GlobalFilter所有路由实现接口并注册为 Bean全局日志、认证拦截
GatewayFilter指定路由(通过配置激活)自定义 Filter 或使用内置过滤器参数修改、路径重写

5. 如何在 Spring Cloud Gateway 中实现限流和熔断?

参考答案
限流实现(以 Sentinel 为例):

  1. 添加依赖:

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
  2. 配置限流规则(如 Nacos 配置中心):

    [
      {
        "resource": "user-service",
        "count": 100, // 阈值
        "intervalSec": 1 // 统计窗口(秒)
      }
    ]
    

熔断实现(结合 Resilience4j):

spring:
  cloud:
    gateway:
      routes:
        - id: product-service
          uri: lb://product-service
          filters:
            - name: CircuitBreaker
              args:
                name: productCircuitBreaker
                fallbackUri: forward:/fallback/product

6. Gateway 的负载均衡是如何实现的?

参考答案
Spring Cloud Gateway 通过LoadBalancerClient接口实现负载均衡,核心流程:

  1. 路由配置中使用lb://service-name格式的 URI,标识启用负载均衡。
  2. 集成注册中心(如 Nacos、Eureka)获取服务实例列表。
  3. 默认采用RoundRobinLoadBalancer(轮询)算法选择实例,也可自定义负载均衡策略。
  4. 通过ReactiveLoadBalancer实现异步非阻塞的负载均衡调用。

7. Gateway 的过滤器执行顺序如何控制?

参考答案
过滤器顺序由Ordered接口的getOrder()方法返回值决定:

  • 数值越小:优先级越高,越早执行(请求时先执行,响应时后执行)。

  • 全局过滤器路由过滤器的执行顺序:

    1. 全局前置过滤器(按 Order 排序)

    2. 路由过滤器(按配置顺序)

    3. 全局后置过滤器(按 Order 逆序)

示例

@Component
public class PreFilter implements GlobalFilter, Ordered {
    @Override
    public int getOrder() { return -1; } // 高优先级
}

@Component
public class PostFilter implements GlobalFilter, Ordered {
    @Override
    public int getOrder() { return 1; } // 低优先级
}

8. Gateway 如何处理跨域请求(CORS)?

参考答案

  1. 全局配置(推荐):

    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOriginPattern("*"); // 允许所有域名
        config.addAllowedMethod("*");
        config.addAllowedHeader("*");
        config.setAllowCredentials(true);
        
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
    
  2. 路由配置

    spring:
      cloud:
        gateway:
          globalcors:
            corsConfigurations:
              '[/**]':
                allowedOrigins: "*"
                allowedMethods: "*"
                allowedHeaders: "*"
    

9. Gateway 的 Hystrix 断路器与 Sentinel 熔断的区别?

参考答案

对比项HystrixSentinel
状态监控依赖 Dashboard,功能较单一提供可视化控制台,支持实时监控
熔断策略基于错误率和超时支持流量控制、熔断降级、系统保护
扩展性社区活跃度低,停止更新阿里开源,持续维护,生态完善
集成方式通过 Netflix Ribbon 集成原生支持 Spring Cloud Gateway
隔离模式线程池 / 信号量隔离信号量隔离

10. 如何在 Gateway 中实现请求参数的修改或加密?

参考答案
通过自定义全局过滤器拦截并修改请求参数:

@Component
public class ParameterFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        
        // 读取并修改参数
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>(request.getQueryParams());
        params.add("encrypted", "true");
        
        // 构建新请求
        ServerHttpRequest newRequest = request.mutate()
            .uri(UriComponentsBuilder.fromUri(request.getURI()).queryParams(params).build().toUri())
            .build();
            
        return chain.filter(exchange.mutate().request(newRequest).build());
    }
    @Override
    public int getOrder() { return 0; }
}

11. Gateway 的动态路由如何实现?

参考答案

  1. 基于配置中心(如 Nacos、Config Server):

    • 将路由配置存储在配置中心,网关启动时加载。
    • 配置变更时,通过 Spring Cloud Bus 或手动刷新触发路由更新。
  2. 自定义路由 Locator

    @Component
    public class DynamicRouteLocator implements RouteDefinitionLocator {
        @Override
        public Flux<RouteDefinition> getRouteDefinitions() {
            // 从数据库或其他存储动态加载路由定义
            return Flux.fromIterable(loadRoutesFromDB());
        }
    }
    

12. Gateway 的错误处理机制是怎样的?

参考答案

  1. 全局异常处理器

    @Component
    public class GlobalExceptionHandler implements ErrorWebExceptionHandler {
        @Override
        public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
            // 自定义异常处理逻辑
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
            return response.setComplete();
        }
    }
    
  2. 熔断降级处理

    spring:
      cloud:
        gateway:
          default-filters:
            - name: Hystrix
              args:
                name: fallbackCommand
                fallbackUri: forward:/fallback
    

13. Gateway 的性能优化有哪些方向?

参考答案

  1. 合理配置线程池

    spring:
      cloud:
        gateway:
          threads:
            worker:
              threads: 16 # 根据CPU核心数调整
    
  2. 缓存机制:对静态资源或高频请求结果添加缓存。

  3. 压缩响应:启用 gzip 压缩减少数据传输量。

  4. 连接池优化:配置 HttpClient 连接池参数。

  5. 避免阻塞操作:在过滤器中使用非阻塞 API。

14. Gateway 与 OAuth2.0 的集成方式有哪些?

参考答案

  1. 资源服务器模式

    • Gateway 作为 OAuth2 资源服务器,验证 JWT 令牌。
    spring:
      security:
        oauth2:
          resourceserver:
            jwt:
              issuer-uri: https://auth-server.com
    
  2. Token 中继模式

    • Gateway 验证令牌后,将令牌转发给下游服务。
    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http.oauth2ResourceServer().jwt();
        return http.build();
    }
    

15. Gateway 的核心组件有哪些?简述其工作流程。

参考答案
核心组件

  • RouteLocator:路由定位器,负责加载路由定义。

  • RouteDefinition:路由配置,包含 ID、URI、断言和过滤器。

  • Predicate:断言,用于匹配请求条件(如 Path、Method)。

  • GatewayFilter:过滤器,处理请求 / 响应(如添加 Header、限流)。

  • GlobalFilter:全局过滤器,作用于所有路由。

工作流程

  1. 请求进入 Gateway,由RoutePredicateHandlerMapping匹配路由。
  2. 匹配成功后,构建过滤器链(包括全局和路由过滤器)。
  3. 请求依次经过前置过滤器处理,转发到目标服务。
  4. 服务响应返回,经过后置过滤器处理后返回客户端。

16. Gateway 如何与注册中心(如 Nacos)集成实现服务发现?

参考答案

  1. 添加依赖:

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
  2. 配置注册中心地址:

    spring:
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848
    
  3. 启用服务发现路由:

    spring:
      cloud:
        gateway:
          discovery:
            locator:
              enabled: true
              lower-case-service-id: true
    

17. Gateway 的长连接(WebSocket)支持如何实现?

参考答案

  1. 配置路由时指定WebSocket协议:

    yaml

    spring:
      cloud:
        gateway:
          routes:
            - id: websocket-route
              uri: ws://backend-service
              predicates:
                - Path=/ws/**
    
  2. 添加 WebSocket 依赖:

    xml

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    

18. Gateway 的跨域配置与普通 Spring Boot 应用有何不同?

参考答案

  • 普通应用:通过WebMvcConfigureraddCorsMappings配置。

  • Gateway:需使用CorsWebFilter或全局 CORS 配置,因为 Gateway 基于 WebFlux 而非 Servlet。

    @Bean
    public CorsWebFilter corsFilter() {
        // 配置CORS规则
    }
    

19. Gateway 的路由断言(Predicate)支持哪些时间相关的匹配?

参考答案

  • After:请求时间在指定日期之后。

    yaml

    predicates:
      - After=2023-01-01T00:00:00+08:00[Asia/Shanghai]
    
  • Before:请求时间在指定日期之前。

  • Between:请求时间在指定两个日期之间。

20. Gateway 如何实现灰度发布?

参考答案

  1. 基于请求头或参数

    @Component
    public class GrayScaleFilter implements GlobalFilter {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            String version = exchange.getRequest().getHeaders().getFirst("version");
            // 根据版本号路由到不同服务
            return chain.filter(exchange);
        }
    }
    
  2. 结合注册中心

    • 服务实例注册时携带元数据(如version=v1)。
    • Gateway 根据请求特征(如用户 ID)选择目标版本。

21. Gateway 的过滤器中如何获取请求体(RequestBody)?

参考答案
由于请求体是一次性读取的流,需特殊处理:

@Component
public class RequestBodyFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return DataBufferUtils.join(exchange.getRequest().getBody())
            .flatMap(dataBuffer -> {
                byte[] bytes = new byte[dataBuffer.readableByteCount()];
                dataBuffer.read(bytes);
                DataBufferUtils.release(dataBuffer);
                
                String body = new String(bytes, StandardCharsets.UTF_8);
                // 处理请求体
                
                // 重新构建请求
                ServerHttpRequest newRequest = exchange.getRequest().mutate()
                    .body(Flux.just(exchange.getResponse().bufferFactory().wrap(bytes)))
                    .build();
                    
                return chain.filter(exchange.mutate().request(newRequest).build());
            });
    }
}

22. Gateway 的高可用架构如何设计?

参考答案

  1. 集群部署:多实例 Gateway 通过负载均衡器(如 Nginx、AWS ELB)对外提供服务。
  2. 会话保持:使用 IP 哈希或 Sticky Session 确保同一用户请求路由到同一 Gateway 实例。
  3. 配置中心:路由规则存储在配置中心(如 Nacos、Consul),动态刷新。
  4. 监控告警:集成 Prometheus+Grafana 监控性能,配置异常告警。

23. Gateway 与 OpenAPI(Swagger)如何集成?

参考答案

  1. 网关聚合文档

    • 各微服务暴露 Swagger 接口(如/v2/api-docs)。
    • Gateway 路由到各服务的文档接口,并通过自定义过滤器聚合。
  2. 推荐组件

    • springdoc-openapi:支持 Spring WebFlux 和 Gateway,自动生成聚合文档。

24. Gateway 的热更新路由如何实现?

参考答案

  1. 基于配置中心(如 Nacos):

    • 路由配置存储在 Nacos,变更时触发 Gateway 刷新。
    spring:
      cloud:
        gateway:
          discovery:
            locator:
              enabled: true
      refresh:
        enabled: true
    
  2. API 动态更新

    • 暴露管理接口,通过RouteDefinitionWriter动态添加 / 删除路由。

25. Gateway 的性能瓶颈通常出现在哪些环节?如何排查?

参考答案
常见瓶颈

  • 过滤器链过长或包含阻塞操作。

  • 与注册中心通信延迟。

  • 负载均衡策略不合理。

排查方法

  1. 启用 Gateway 的调试日志:

    logging:
      level:
        org.springframework.cloud.gateway: DEBUG
    
  2. 使用 Micrometer 集成 Prometheus+Grafana 监控请求耗时。

  3. 分析 GC 日志和线程 dump,定位阻塞点。

26. Gateway 如何实现请求的重试机制?

参考答案
使用RetryGatewayFilterFactory

spring:
  cloud:
    gateway:
      routes:
        - id: retry_route
          uri: lb://backend-service
          predicates:
            - Path=/api/**
          filters:
            - name: Retry
              args:
                retries: 3
                statuses: SERVICE_UNAVAILABLE
                methods: GET,POST
                backoff:
                  firstBackoff: 500ms
                  maxBackoff: 5000ms
                  factor: 2
                  basedOnPreviousValue: false

27. Gateway 的线程模型是怎样的?

参考答案
Gateway 基于 Netty 和 Reactor 模型,核心线程池:

  1. EventLoopGroup(默认 2×CPU 核心数):处理网络 IO。
  2. Worker 线程池:执行非阻塞任务(如过滤器逻辑)。
  3. 自定义线程池:对于阻塞操作,需配置独立线程池避免阻塞 EventLoop。

28. Gateway 与服务网格(如 Istio)的关系是什么?

参考答案

  • Gateway:作为 API 网关,侧重流量入口控制、协议转换、认证授权。

  • Istio:作为服务网格,侧重服务间通信、流量治理、可观测性。

协作模式
Gateway 作为边缘网关处理外部请求,Istio 管理内部微服务间通信,形成互补。

29. Gateway 如何处理大文件上传?

参考答案

  1. 调整 Netty 服务器配置:

    spring:
      codec:
        max-in-memory-size: 100MB # 增加内存缓冲区大小
    
  2. 使用流式处理避免内存溢出:

    @Component
    public class LargeFileFilter implements GlobalFilter {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 使用DataBufferUtils处理大文件流
            return chain.filter(exchange);
        }
    }
    

30. Gateway 的过滤器中如何实现异步操作?

参考答案
使用 Reactor 的异步 API,例如:

@Component
public class AsyncFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return Mono.fromCallable(() -> {
                // 执行异步操作(如调用外部服务)
                return "async-result";
            })
            .subscribeOn(Schedulers.boundedElastic())
            .flatMap(result -> {
                // 处理结果并继续过滤器链
                return chain.filter(exchange);
            });
    }
}