FeignClient spi 呼叫 短路異常 & 執行緒池配置
FeignClient spi 呼叫 短路異常 & 執行緒池配置
預設配置見:
HystrixThreadPoolProperties
執行緒池物件:com.netflix.hystrix.HystrixThreadPool
1. 問題
最近專案中使用FeignClient
呼叫公共訊息服務的spi時候,突然出現了一下錯誤:
MessageSpi.sendMessage could not be queued for execution and fallback disabled.
然後很快出現了短路錯誤:
MessageSpi.sendMessage short-circuited and fallback disabled.
2. 依賴介面效能解決
反饋給介面提供方後,他們說是呼叫方配置的執行緒池滿了,而為什麼滿,他們懷疑是自己的介面效能慢導致。所以他們去優化介面的效能即可。我們無需關注執行緒池滿的原因。
不過問題很快又找到我了。
接下來的另一個專案是一個類似請求轉發&返回值封裝的中間層服務,主要請求都是通過SPI
的方式呼叫其他服務。結果在壓測時一下子就報錯誤了,和上面提到的錯誤是一樣的。
這個時候,如果還是找介面效能就不那麼靠譜了。因為即使介面效能在100ms的情況下,支援100qps的併發還是很easy。
3. 原因
後面通過本地斷點,發現FeignClient
使用的執行緒池是com.netflix.hystrix.HystrixThreadPool
ThreadPoolExecutor
,他預設的執行緒池數量是10(可以從HystrixThreadPoolProperties
這裡看到),佇列-1,表示同步佇列。
而元件裡配置的預設執行緒池大小是30,佇列的大小也是30.
假設介面效能在 50ms,那麼這個配置,最大的qps 應該是 30 * (1000/50),也就是 600qps。
表面上看這個配置是夠用的,但是依賴介面的效能,因為如果是100ms ,那麼就瞬間降到300qps。
而按照預設的配置,這個值是200qps,要求低一點就是100qps。
而且可能由於瞬時的流量,導致響應慢後佇列就很可能慢,然後導致了以上的錯誤。
4. 根據你的業務場景來配置
2中的問題不一樣,他是一個流量轉發的任務,在本地耗時的時間短,基本都是spi耗時,所以它的執行緒池的配置應該是和該服務容器執行緒差不多才行。
所以我們執行緒池的配置如下:
hystrix:
threadpool:
default:
coreSize: 200 #併發執行的最大執行緒數,預設10
maxinumPoolSize: 300 # 最大執行緒數
maxQueueSize: 100 #BlockingQueue的最大佇列數,預設值-1
queueSizeRejectionThreshold: 80 #即使maxQueueSize沒有達到,達到queueSizeRejectionThreshold該值後,請求也會被拒絕,預設值5
另外,default是 預設的配置,從com.netflix.hystrix.HystrixThreadPool.Factory#threadPools
這裡我們可以看到,執行緒池的配置還可以按照不同的FeignClient
配置不同的執行緒池,依據你自己的場景去配置就好
hystrix:
threadpool:
message-server: # 對應 message-sever 對應的 FeignClient SPI
coreSize: 200
maxinumPoolSize: 300 # 最大執行緒數
maxQueueSize: 100 #BlockingQueue的最大佇列數,預設值-1
queueSizeRejectionThreshold: 80