Spring Cloud Gateway Hystrix Filter fallbackUri 無效問題

首先,介紹下問題:

一個plat-gateway工程,配置了Hystrix。按照通用的配置,如下驗證:

@RestController
public class SelfHystrixController {
    @RequestMapping("/defaultfallback")
    public Map<String,String> defaultfallback(){
    	log.info(LogMessage.getMessage("", "請求被熔斷了"));
        Map<String,String> map = new HashMap<>();
        map.put("msg","網絡繁忙服務降級請稍後再訪問");
        map.put("code","GW0001");
        return map;
    }

    /**
     * 發起Get 請求 :localhost:8000/gateway/timeout
     * 會進行熔斷
     * @return
     */
    @RequestMapping("/timeout")
    public String timeout(){
        try {
            Thread.sleep(15000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "Hello, I am timeout return. If normal, you can not find me.";
    }
}

Yml配置如下:

  cloud:
    # Gateway routes config
    gateway:
      default-filters:
        - name: Hystrix
          args:
            name: fallbackcmd
            fallbackUri: forward:/defaultfallback
      routes:
        # 走 fsp 的路由
        - id: wish.plat-gateway.fsp
          uri: http://127.0.0.1:80
          order: 2
          #網關斷言匹配
          predicates:
            - Path=/gateway/**
          filters:
            # - StripPrefix=4
            - FspAdapt

如上,在controller中驗證是沒有問題的。但是發現,在 FspAdaptGatewayFilterFactory 的過濾器中,是無法熔斷。

配置 10s熔斷, 在過濾器中休眠 15s,執行post請求。期望是:到10s後,主動熔斷,返回前端信息。but,現實情況是,到達10秒後,繼續執行,執行完後,才返回前端。此時信息是:

{
    "timestamp": "2019-10-31T00:54:57.352+0000",
    "path": "/gateway/04320/07/B70001/arrange/newBusiness/1233333",
    "status": 504,
    "error": "Gateway Timeout",
    "message": "Response took longer than configured timeout"
}

本人想過很多方案,第一:修改spring-cloud-gateway-core中的TimeoutException,爲RuntimeException,這樣就可以終止繼續執行了。第二:自定義一個  HystrixGatewayFilterFactory 來實現該功能。但是思來想去,spring cloud hystrix不應該這樣。因爲根本未達到熔斷的目的,猜想是對使用不夠深入瞭解。

在這樣一篇文章中,Spring Cloud Hystrix設計原理。請認真閱覽,發現如下是跟我相關的描述:

如果run() 或者construct()方法 的真實執行時間超過了Command設置的超時時間閾值, 則當前則執行線程(或者是獨立的定時器線程)將會拋出TimeoutException。拋出超時異常TimeoutException,後,將執行步驟8的Fallback降級處理。即使run()或者construct()執行沒有被取消或中斷,最終能夠處理返回結果,但在降級處理邏輯中,將會拋棄run()或construct()方法的返回結果,而返回Fallback降級處理結果。

需要注意的是,Hystrix無法強制 將正在運行的線程停止掉--Hystrix能夠做的最好的方式就是在JVM中拋出一個InterruptedException。如果Hystrix包裝的工作不拋出中斷異常InterruptedException, 則在Hystrix線程池中的線程將會繼續執行,儘管調用的客戶端已經接收到了TimeoutException。這種方式會使Hystrix 的線程池處於飽和狀態。大部分的Java Http Client 開源庫並不會解析 InterruptedException。所以確認HTTP client 相關的連接和讀/寫相關的超時時間設置。

3.1 斷路器相關配置:
circuitBreaker.forceOpen    是否強制將斷路器設置成開啓狀態    false

心想,這不就是說的我這種情況嗎?於是覺得可以查閱http的超時或者circuitBreaker.forceOpen來試一下。

美好的事情,總會發生。增加如下配置,生效了:

#熔斷相關配置            
hystrix:
  command:
    default:
      circuitBreaker:
        # 強制將斷路器設置成開啓狀態
        forceOpen: true

此刻,整個世界都好了。等等,本以爲到此結束,萬萬沒想到。

接下來,配置  timeoutInMilliseconds: 10000 ,去掉過濾器中的休眠,打算正常測試下。結果:熔斷,熔斷,熔斷。是的,連正常功能都不好使了,嚇得我趕緊去掉了這個參數。仔細一想,這個參數是,強制熔斷。so,不能隨便亂用。

http請求的超時,未找到相關設置。

結論:可能與設計原理,不是很一致,因此通過配置可能無法實現。暫時擱置/自定義過濾器實現/考慮下其他方案,如Sentinel等。

不急,時間會說明一切。(未完,待續)

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