• SpringCloudGateway网关实战(二)


    SpringCloudGateway网关实战(二)

    本文我们在前文的基础上,开始讲gateway过滤器的部分内容。gateway的过滤器分为内置过滤器Filter和全局过滤器GlobalFilter。本章节先讲内置过滤器Filter。

    需要先声明一下内置过滤器和全局过滤器之间的区别:

    • 内置过滤器是针对特定路由定义的,只在匹配到该路由的请求上运行。
    • 全局过滤器是应用于所有路由的通用过滤器,无需为每个路由单独配置。

    通常情况下,会根据路由的具体需求选择并配置不同的内置过滤器来完成特定的功能。如果有一些通用的过滤逻辑需要应用到所有的请求上,可以选择使用全局过滤器来实现。

    内置过滤器Filter

    内置过滤器其实挺多的,这里挑一些常用的说一下:

    1. StripPrefix:去除请求的前缀。
    2. RewritePath:重写请求的路径。
    3. RateLimiter:限流过滤器,用于控制请求的速率。
    4. Retry:对请求进行重试。
    5. AddRequestHeader:用于添加请求头。
    6. AddResponseHeader:在响应头中添加指定的键值对。
    7. SetRequestHeader:设置请求头的值。
    8. SetResponseHeader:设置响应头的值。
    9. AddRequestParameter:添加请求参数。
    10. RemoveRequestHeader:移除请求头。
    11. RemoveResponseHeader:移除响应头。
    12. Hystrix:将请求包裹在Hystrix断路器中,提供服务容错能力。

    1.StripPrefix

    spring:
      cloud:
        gateway:
          routes:
            - id: system-api
              uri: lb://system-api
              predicates:
                - Path=/system-api/**
              filters:
                - StripPrefix=1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这个是最常用的过滤器,作用是过滤掉url中前n节,比如我们发送请求:

    localhost:8080/system-api/system/user/info
    
    • 1

    此时因为我们配置了StripPrefix=1,实际请求的地址就变成:

    localhost:8080/system/user/info
    
    • 1

    2.RewritePath

    spring:
      cloud:
        gateway:
          routes:
            - id: system-api
              uri: lb://system-api
              predicates:
                - Path=/system-api/**
    		 filters:
    		   - StripPrefix=1
                - RewritePath=/system/(?>.*), /$\{segment}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    具体的重写规则为将 “/system/xxx” 重写为 “/xxx”,其中 xxx 是根据正则表达式捕获的片段(segment)。

    比如发起请求:

    localhost:8080/system-api/system/user/info
    
    • 1

    那么该请求就会请求到:

    localhost:8080/user/info
    
    • 1

    3.RateLimiter

    spring:
      cloud:
        gateway:
          routes:
            - id: system-api
              uri: lb://system-api
              predicates:
                - Path=/system-api/**
              filters:
                - StripPrefix=1
                - name: RequestRateLimiter
                  args:
                    key-resolver: "#{@remoteAddrKeyResolver}" # 使用 SpEL 表达式按名称引用 bean
                    redis-rate-limiter.replenishRate: 10 # 令牌桶每秒填充速率
                    redis-rate-limiter.burstCapacity: 20 # 令牌桶总容量
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在上面的示例中,我们使用了 name: RequestRateLimiter 来指定使用 RateLimiter 过滤器,并通过 args 属性来设置 RateLimiter 过滤器的参数。

    在这个示例中,我们设置了以下参数:

    • key-resolver: "#{@remoteAddrKeyResolver}":用于指定从请求中提取限流键的解析器。你可以自定义一个实现了 KeyResolver 接口的 Bean,并在此处引用它。
    • redis-rate-limiter.replenishRate: 10:限流桶每秒填充的令牌数为 10。
    • redis-rate-limiter.burstCapacity: 20:限流桶的容量为 20。

    由于这个限流过滤器是使用Redis进行实现的,所以我们需要引入对应的Redis依赖,并配置对应的Redis配置。

    引入依赖:

            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-data-redisartifactId>
            dependency>
    
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-data-redis-reactiveartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    添加Redis配置:

    spring:
      redis:
        host: localhost                # Redis 主机名
        port: 6379                     # Redis 端口号
        password: 123456             # Redis 密码(如果有的话)
        timeout: 2000                  # 连接超时时间(毫秒)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    对应的KeyResolver配置类:

    @Configuration
    public class KeyResolverConfiguration {
    
        @Primary
        @Bean
        public KeyResolver remoteAddrKeyResolver() {
            return exchange -> Mono
                    .just(Objects.requireNonNull(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()))
                            .getAddress().getHostAddress());
        }
    
        @Bean
        public KeyResolver pathKeyResolver() {
            return exchange -> Mono.just(exchange.getRequest().getURI().getPath());
        }
    
        @Bean
        public KeyResolver ipKeyResolver() {
            return exchange -> Mono.just(exchange.getRequest().getURI().getHost());
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    这样,我们启动应用,进行压力测试:

    image-20230905230718282

    这里我们可以看到,我们进行了5秒压测,由于我们的配置:

                    redis-rate-limiter.replenishRate: 10
                    redis-rate-limiter.burstCapacity: 20
    
    • 1
    • 2

    所以令牌桶中初始有20个令牌,而每秒钟10个令牌的速率重新填充。我们压测进行了5秒,因此结果有20+5*10=70个请求请求成功,理论与我们的压测结果达到了一致。

    4.Retry

    spring:
      cloud:
        gateway:
          routes:
            - id: system-api
              uri: lb://system-api
              predicates:
                - Path=/system-api/**
              filters:
                - StripPrefix=1
                - name: Retry
                  args:
                    retries: 3
                    statuses: BAD_GATEWAY,INTERNAL_SERVER_ERROR
                    methods: GET,POST
                    series: SERVER_ERROR
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    如上图示例,我们使用了 name: Retry 来指定使用 Retry 过滤器,并通过 args 属性来设置 Retry 过滤器的参数。在这个示例中,我们设置了以下参数:

    • retries: 3:最大重试次数为 3。
    • statuses: BAD_GATEWAY,INTERNAL_SERVER_ERROR:当响应状态码为 BAD_GATEWAYINTERNAL_SERVER_ERROR 时触发重试。取值参考:org.springframework.http.HttpStatus
    • methods: GET,POST:只对 GET 和 POST 请求方法进行重试。取值参考:org.springframework.http.HttpMethod
    • series: SERVER_ERROR:只对服务器错误类别的响应进行重试(即状态码以 5 开头的响应)。org.springframework.http.HttpStatus.Series

    5.AddRequestHeader

    spring:
      cloud:
        gateway:
          routes:
            - id: system-api
              uri: lb://system-api
              predicates:
                - Path=/system-api/**
              filters:
                - StripPrefix=1
                - AddRequestHeader=X-Example-Header, example-value
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在上述示例中,AddRequestHeader过滤器将在请求的头部中添加一个名为X-Example-Header的字段,并设置其值为example-value。通过这种方式,当请求被转发到目标服务时,就会携带额外的请求头信息。后续的服务可以读取这些请求头并进行相应的处理。

    6.AddResponseHeader

    spring:
      cloud:
        gateway:
          routes:
            - id: system-api
              uri: lb://system-api
              predicates:
                - Path=/system-api/**
              filters:
                - StripPrefix=1
                - AddResponseHeader=X-Example-Header, example-value
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在上述示例中,AddResponseHeader过滤器会在响应的头部中添加一个名为X-Example-Header的字段,并设置其值为example-value。通过这种方式,目标服务返回的响应会携带额外的响应头信息。

    7.SetRequestHeader

    spring:
      cloud:
        gateway:
          routes:
            - id: system-api
              uri: lb://system-api
              predicates:
                - Path=/system-api/**
              filters:
                - StripPrefix=1
                - SetRequestHeader=X-Custom-Header, custom-value
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在上述示例中,当匹配成功时,会使用 SetRequestHeader 过滤器来设置请求头X-Custom-Header,并指定其值为 custom-value

    8.SetResponseHeader

    spring:
      cloud:
        gateway:
          routes:
            - id: system-api
              uri: lb://system-api
              predicates:
                - Path=/system-api/**
              filters:
                - StripPrefix=1
                - SetResponseHeader=X-Custom-Header, custom-value
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在上述示例中,当匹配成功时,会使用 SetResponseHeader 过滤器来设置响应头X-Custom-Header,并指定其值为 custom-value

    9.AddRequestParameter

    spring:
      cloud:
        gateway:
          routes:
            - id: system-api
              uri: lb://system-api
              predicates:
                - Path=/system-api/**
              filters:
                - StripPrefix=1
                - AddRequestParameter=apiKey,my-value
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在上面的例子中,我们使用AddRequestParameter过滤器并提供了两个参数:

    • apiKey:要添加的请求参数的名称。
    • my-value:要添加的请求参数的值。

    通过这个配置,当请求匹配时,将会自动添加一个名为apiKey,值为my-value的请求参数。

    10.RemoveRequestHeader

    spring:
      cloud:
        gateway:
          routes:
            - id: system-api
              uri: lb://system-api
              predicates:
                - Path=/system-api/**
              filters:
                - StripPrefix=1
                - name: RemoveRequestHeader
                  args:
                    name: X-Auth-Token
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    上面示例中,我们使用了 name: RemoveRequestHeader 来指定使用 RemoveRequestHeader 过滤器。通过 args 属性来设置 RemoveRequestHeader 过滤器的参数。

    在这个示例中,我们设置了以下参数:

    • name: X-Auth-Token:要移除的请求头的名称。

    这样配置之后,当请求匹配时,将会自动移除请求中的 X-Auth-Token 请求头,并将修改后的请求继续传递给对应服务。

    11.RemoveResponseHeader

    spring:
      cloud:
        gateway:
          routes:
            - id: system-api
              uri: lb://system-api
              predicates:
                - Path=/system-api/**
              filters:
                - StripPrefix=1
                - name: RemoveResponseHeader
                  args:
                    name: X-Custom-Header
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    上面例子中,我们使用了 name: RemoveResponseHeader 来指定使用 RemoveResponseHeader 过滤器。通过 args 属性来设置 RemoveResponseHeader 过滤器的参数。

    在这个示例中,我们设置了以下参数:

    • name: X-Custom-Header:要移除的响应头的名称。

    这样配置之后,当请求匹配时,将会自动移除响应中的 X-Custom-Header 响应头,并将修改后的响应返回给客户端。

    12.Hystrix

    这部分有点特殊,在3.1.8版本的spring-cloud-starter-gateway中,Hystrix这个Filter已经被正式移除了,这之后更加倾向于单独使用Hystrix而不是在gateway中的Hystrix

    如果你想要按照:

              filters:
                - name: Hystrix
                  args:
                    name: fallbackcmd
                    fallbackUri: forward:/fallback
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这样的形式尝试使用Hystrix,那么就会报错Unable to find GatewayFilterFactory with name hystrix

    另外使用Hystrix我们后面再讲。

  • 相关阅读:
    ubunu 18.04 LTS安装Qt-5.14-2并一起安装Qt Creator
    JVM常用参数解释说明
    [C/C++]天天酷跑超详细教程-中篇
    分享大数据分析培训就业班课程内容
    【uvm】DUT 和 testbench 是如何连接的
    [python3] 发送微信 同步手机端
    【训练方法】OHEM
    postgresql数据库备份
    低开开发笔记(四):实现编辑器内拖拽
    蓝桥杯--挖地雷
  • 原文地址:https://blog.csdn.net/zz_smallred/article/details/132794241