spring cloud gateway 踩的一些坑及解决办法

2022-07-04 08:08:21

1. ribbon 快速失败,断路功能无法应用


这个问题无解:
    网关LoadBalancerClientFilter只是使用ribbon的负载均衡策略
    没有将后续的错误计数应用上,导致不会将错误(超时,异常)的服务进行移除

    https://github.com/spring-cloud/spring-cloud-gateway/issues/568

2. lb 请求默认会将服务名称去掉


  如:
   http://192.168.0.100:8080/system/test ——> http://192.168.0.100:8080/test
  这是因为默认配置了 RewritePath
  只要重写过滤链即可,添加如下配置,覆盖默认:

  spring:
      cloud:
        gateway:
          discovery:
              filters:
                - PreserveHostHeader

3. discovery.filters,default-filters区别


       discovery.filters: 只有从注册中心建立的路由的才会附加(lb)
       default-filters: 所有的路由都会增加

spring:
  cloud:
    gateway:
      discovery:
          filters:
          
      default-filters:

4. 重试(el)配置


   discovery.filters 不支持el 表达式配置。
   以下配置  default-filters 正常,discovery.filters  报错;

    default-filters:
        - name: Retry
          args:
            retries: 5
            statuses:
              - BAD_GATEWAY
              - GATEWAY_TIMEOUT



5. 增加重试配置


     通过下面的配置就可以增加重试,默认只有GET方法重试,重试3次。
     只有以下异常进行重试:
        IOException
        org.springframework.cloud.gateway.support.TimeoutException

 default-filters:
        - Retry


6. gateway httpClient 连接超时控制

gateway 默认使用 netty httpClient 实现。
可以通过下面的参数进行控制;

spring:
  cloud:
    gateway:
      httpclient:
        connectTimeout: 2000
        responseTimeout: 10s


注意: 如果有配置重试(retry):
    connectTimeout 会进行重试
    responseTimeout 不会触发重试(可能是一种BUG),

因为 responseTimeout 被包装成了 ResponseStatusException ,所以没有重试


https://github.com/spring-cloud/spring-cloud-gateway/issues/821

7. retry Hystrix 重试

retry 与 Hystrix 的顺序,决定谁包含谁

Hystrix 在前:
    不管重试几次,都只会按照Hystrix超时时间为准。
    如果Hystrix超时了,也就不会重试了
retry 在前:
    Hystrix超时了也会重试

通过这种关系,我们可以配置两个 Hystrix,一个控制整个请求的时间,一个控制单次重试的时间
再单次超时时(如果有配置 responseTimeout),将异常进行转换,达到responseTimeout也能重试的效果

配置如下:

 default-filters:
        - name: Hystrix
          args:
            name: globalcmd
            fallbackUri: forward:/errorFallback
        - name: Retry
          args:
            statuses:
              - BAD_GATEWAY
              - GATEWAY_TIMEOUT
        - name: Hystrix
          args:
            name: retrycmd
            fallbackUri: forward:/retryFallback


代码:

    @RequestMapping(value = "/retryFallback")
    public Mono<ActionResult> retryFallback(ServerWebExchange exchange) {
        Exception e = exchange.getAttribute(ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR);
        if( e instanceof ResponseStatusException)
        {
            ResponseStatusException exception = (ResponseStatusException)e;
            if(HttpStatus.GATEWAY_TIMEOUT.equals(exception.getStatus()))
            {
                return Mono.error(new TimeoutException(exception.getMessage()));
            }
        }
        return Mono.error(e);
    }

-------

版本:

<spring-cloud-dependencies.version>Greenwich.SR2</spring-cloud-dependencies.version>
<spring-boot-dependencies.version>2.1.6.RELEASE</spring-boot-dependencies.version>
  • 作者:xiaolaoban212
  • 原文链接:https://blog.csdn.net/xiaolaoban212/article/details/97375629
    更新时间:2022-07-04 08:08:21