• Spring Gateway 网关常见配置说明


    前言

    Spring Gateway 是基于 Spring Framework 的 API 网关,它为微服务架构提供了路由、监控、弹性以及安全性等功能。Spring Gateway 使用非阻塞 API 和高性能的反应式编程模型来提供服务。

    版本说明

    本文的选项在多个最近的 Spring Cloud Gateway 版本中都是有效的,比如 Spring Cloud 2020.0.x 至 2021.0.x 版本系列。与 Spring Boot 2.3.x 至 2.6.x 版本兼容。

    基础配置

    以下是一个完整的 Spring Gateway 配置示例,包含了常见的路由配置、过滤器使用、全局过滤器配置以及一些其他常用的设置。这些配置将在 application.yml 文件中进行设置:

    spring:
      cloud:
        gateway:
          # 路由配置列表
          routes:
            # 第一条路由规则
            - id: route1
              uri: http://example.org
              predicates:
                - Path=/api/service1/**  # 路径匹配规则
              filters:
                - AddRequestHeader=X-Request-Foo, Bar  # 添加请求头
    
            # 第二条路由规则
            - id: route2
              uri: http://example.com
              predicates:
                - Path=/api/service2/**
                - Method=GET,POST  # 只允许 GET 和 POST 方法
              filters:
                - RewritePath=/api/service2/(?>.*), /$\{segment}  # URL 重写
    
          # 全局过滤器配置
          default-filters:
            - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin  # 去重HTTP响应头
    
          # 用于控制 HTTP 请求的负载均衡器配置
          loadbalancer:
            use404: true  # 当无可用服务时返回404
    
          # HTTP请求重试配置
          retry:
            enabled: true
            retries: 3  # 重试次数
            statuses: BAD_GATEWAY,GATEWAY_TIMEOUT  # 触发重试的HTTP状态码
            methods: GET,POST  # 允许重试的HTTP方法
            backoff:
              firstBackoff: 50ms  # 首次重试的延迟
              maxBackoff: 500ms  # 最大重试延迟
              factor: 2  # 延迟因子
              basedOnPreviousValue: false  # 延迟是否基于上一次的延迟时间
    
          # 跨域配置
          globalcors:
            corsConfigurations:
              '[/**]':
                allowedOrigins: "*"  # 允许所有域
                allowedMethods: "*"  # 允许所有方法
                allowedHeaders: "*"  # 允许所有头
                allowCredentials: true  # 允许证书
    
    # Spring 应用名称
    spring:
      application:
        name: gateway-service
    
    # 服务端口
    server:
      port: 8080
    
    # 日志配置
    logging:
      level:
        org.springframework.cloud.gateway: DEBUG  # 设置Spring Gateway的日志级别为DEBUG
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    在这个示例中,配置了两条路由规则,每条规则都设置了特定的路径匹配和过滤器。还配置了全局的过滤器,用于去重响应头。另外还包含了负载均衡器配置、重试机制以及全局跨域资源共享(CORS)配置。

    高级特性

    Spring Cloud Gateway 提供了丰富的配置选项来支持各种高级功能,包括但不限于过滤器自定义、安全性增强、限流、WebSocket 支持和更复杂的路由条件。

    1. 安全配置

    如果你需要将 Spring Security 集成到 Spring Cloud Gateway 中,以增强 API 网关的安全性,你可以添加如下依赖并配置相应的安全规则:

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-securityartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    然后,你可以配置基本的 HTTP 安全规则,如下所示:

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                .antMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2. 限流策略

    限流可以帮助你控制对后端服务的请求频率,防止过载。Spring Cloud Gateway 可以通过集成 Redis 来实现请求的限流:

    spring:
      cloud:
        gateway:
          routes:
            - id: route1
              uri: http://example.org
              predicates:
                - Path=/api/service1/**
              filters:
                - name: RequestRateLimiter
                  args:
                    redis-rate-limiter.replenishRate: 10
                    redis-rate-limiter.burstCapacity: 20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3. WebSocket 支持

    Spring Cloud Gateway 支持 WebSocket 代理,需要适当的路由配置:

    spring:
      cloud:
        gateway:
          routes:
            - id: websocket_route
              uri: ws://example-websocket.org
              predicates:
                - Path=/echo
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4. 动态路由

    在一些场景下,你可能需要动态地添加或删除路由。这可以通过编程方式实现,比如使用 RouteDefinitionWriterApplicationEventPublisher

    @Autowired
    private RouteDefinitionWriter routeWriter;
    
    @Autowired
    private ApplicationEventPublisher publisher;
    
    public void addRoute(RouteDefinition routeDefinition) {
        routeWriter.save(Mono.just(routeDefinition)).subscribe();
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5. 熔断器配置

    Spring Cloud Gateway 集成了 Resilience4j 来提供熔断器支持,可以配置熔断规则来保护后端服务:

    spring:
      cloud:
        gateway:
          routes:
            - id: route1
              uri: http://example.org
              filters:
                - name: CircuitBreaker
                  args:
                    name: backendService
                    fallbackUri: forward:/fallback
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    6. 跟踪和日志记录

    为了更好地监控和诊断网关流量,可以集成 Spring Cloud Sleuth 和 Zipkin 进行调用链跟踪。这可以帮助你详细了解请求如何通过你的网关和服务。首先需要添加 Sleuth 和 Zipkin 的依赖:

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-sleuthartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-sleuth-zipkinartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    配置 Zipkin 的服务地址:

    spring:
      zipkin:
        baseUrl: http://localhost:9411
      sleuth:
        sampler:
          probability: 1.0  # 采样率
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    7. 参数化路由匹配

    Spring Cloud Gateway 允许你根据请求参数、头信息等进行路由匹配。例如,你可以根据请求头中的版本号将流量路由到不同的后端服务:

    spring:
      cloud:
        gateway:
          routes:
            - id: route1
              uri: http://example.org/v1
              predicates:
                - Path=/api/service
                - Header=X-API-Version, v1
            - id: route2
              uri: http://example.org/v2
              predicates:
                - Path=/api/service
                - Header=X-API-Version, v2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    8. 环境特定配置

    在不同的环境(开发、测试、生产)中,你可能需要不同的配置。Spring Cloud Gateway 允许你使用 Spring 的 profile 功能来定义环境特定的配置。例如,你可以为开发环境和生产环境定义不同的路由和过滤器配置:

    ---
    spring:
      profiles: dev
      cloud:
        gateway:
          routes:
            - id: dev_route
              uri: http://dev.example.org
              predicates:
                - Path=/api/dev/**
    
    ---
    spring:
      profiles: prod
      cloud:
        gateway:
          routes:
            - id: prod_route
              uri: http://prod.example.org
              predicates:
                - Path=/api/prod/**
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    9. 响应重写

    在某些情况下,你可能需要修改从后端服务返回的响应。Spring Cloud Gateway 提供了过滤器来重写响应头和响应体:

    spring:
      cloud:
        gateway:
          routes:
            - id: rewrite_response
              uri: http://example.org
              filters:
                - ModifyResponseBody=/path, ${{response.body}} Modified
                - ModifyResponseHeader=X-Response-Header, New-Header-Value
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    10. 自定义过滤器

    如果预置的过滤器不能满足你的需求,你可以实现自己的过滤器。你可以继承 AbstractGatewayFilterFactory 类来创建自定义的过滤器逻辑:

    public class MyCustomFilter extends AbstractGatewayFilterFactory<MyCustomFilter.Config> {
        public static class Config {
            // Put the configuration properties for your filter here
        }
    
        @Override
        public GatewayFilter apply(Config config) {
            return (exchange, chain) -> {
                // custom pre-processing
                return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                    // custom post-processing
                }));
            };
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    继续探索 Spring Cloud Gateway 的高级配置,这些配置可以进一步增强你的网关的功能性和灵活性。以下是一些额外的配置选项和高级用法,它们可以帮助你更好地适应复杂的业务需求:

    11. Hystrix 集成

    虽然 Resilience4j 是现代的断路器选择,但如果你的项目还在使用 Hystrix,Spring Cloud Gateway 也支持与 Hystrix 的集成。你可以为特定路由添加 Hystrix 保护:

    spring:
      cloud:
        gateway:
          routes:
            - id: hystrix_route
              uri: http://example.org
              filters:
                - name: Hystrix
                  args:
                    name: myCommand
                    fallbackUri: forward:/fallback
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    12. 路由验证

    在一些应用场景中,需要对请求进行额外的验证,比如检查请求中的 JWT 令牌。Spring Cloud Gateway 允许通过全局过滤器或路由特定过滤器来实现这一点:

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("token_route", r -> r.path("/token/**")
                .filters(f -> f.filter(new AuthFilter()))
                .uri("http://example.org"))
            .build();
    }
    
    public class AuthFilter implements GatewayFilter {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 实现验证逻辑
            boolean isValid = checkAuthToken(exchange.getRequest());
            if (!isValid) {
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
            return chain.filter(exchange);
        }
    
        private boolean checkAuthToken(ServerHttpRequest request) {
            // 验证逻辑
            return true; // 假设总是有效
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    13. API 版本管理

    你可以通过配置多个路由来支持不同版本的 API,以方便客户端调用最合适的服务版本:

    spring:
      cloud:
        gateway:
          routes:
            - id: api_v1
              uri: http://example.org/v1
              predicates:
                - Path=/api/v1/**
            - id: api_v2
              uri: http://example.org/v2
              predicates:
                - Path=/api/v2/**
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    14. 更多动态路由配置

    Spring Cloud Gateway 允许通过数据库或其他服务动态加载和更改路由配置。这可以通过自定义 RouteDefinitionLocator 实现:

    @Bean
    public RouteDefinitionLocator databaseRouteLocator() {
        return new DatabaseRouteDefinitionLocator();
    }
    
    public class DatabaseRouteDefinitionLocator implements RouteDefinitionLocator {
        @Override
        public Flux<RouteDefinition> getRouteDefinitions() {
            // 从数据库加载路由定义
            return Flux.fromIterable(fetchRoutesFromDatabase());
        }
    
        private List<RouteDefinition> fetchRoutesFromDatabase() {
            // 数据库操作,返回路由定义列表
            return new ArrayList<>();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    15. 定制错误处理

    你可以通过定义自己的 ErrorWebExceptionHandler 来定制网关在遇到错误时的行为:

    @Bean
    @Order(-1)  // 确保它比默认的错误处理器优先级高
    public ErrorWebExceptionHandler myExceptionHandler() {
        return new JsonErrorWebExceptionHandler();
    }
    
    public class JsonErrorWebExceptionHandler implements ErrorWebExceptionHandler {
        @Override
        public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
            exchange.getResponse().setStatusCode(HttpStatus.BAD_GATEWAY);
            // 设置响应体等
            return exchange.getResponse().writeWith(Mono.just(...));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    前端学习路线(三)
    在微信小程序上做一个「博客园年度总结」:解决前端获取接口数据太慢的一种思路
    c++学习day3 c++指针
    Adobe砸200亿添全家桶新成员,Figma后来居上!
    Pytorch之EfficientNetV2图像分类
    安全基础 --- 原型链污染
    springboot系列(十七):集成在线接口文档Swagger2|超级详细,建议收藏
    连接池-归还连接详解(上)
    Spring boot 实战指南(二):Mybatis、动态绑定、多数据源、分页插件、Mybatis-Plus
    自学数据库-redis
  • 原文地址:https://blog.csdn.net/qq_28369007/article/details/138115447