spring cloud gateway 踩的一些坑及解決辦法

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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章