如何解決springcloud feign 首次調用100%失敗的問題
敘述
在高並發情況下發佈應用時,經常會發現監控中有很多超時報錯或者斷路器打開,下圖中可以看到監控情況,測試時也會偶現第一次feign調用出錯,第二次就會恢復正常。
分析
大傢都知道,這裡feign底層是集成的ribbon,這裡ribbon也會有http連接池,這裡的連接池是長連接,定時初始化一批並銷毀舊連接,這裡還包括一些上下文需要初始化,但是在容器初始化好時,ribbon底層的client是未初始化的,當第一次調用時,有一個初始化過程會導致超時,一般情況下會說需要調整超時時間,但是在電商高並發情況下,這裡肯定時不現實的,響應請求都需要ms級別。
解決方案
ribbon饑餓加載
這裡可以通過配置ribbon饑餓加載來減少出錯次數,如下:
ribbon: # 饑餓加載 eager-load: # 是否開啟饑餓加載 enabled: true # 饑餓加載的服務 clients: demo-goods,demo-product
這裡為什麼說不能完全解決呢?因為在發佈時流量切換的瞬間,流量太大,並不是僅僅ribbon需要初始化,hystrix、web容器線程池等都需要初始化或者擴容,這裡也需要耗時,所以這裡的饑餓加載僅僅隻是做到瞭發佈時減少錯誤數。
zuul饑餓加載
網關作為對外請求的入口,zuul內部使用Ribbon調用其他服務,Spring Cloud默認在第一次調用時懶加載Ribbon客戶端。zuul同樣需要維護一個相對的子應用環境的上下文,所以也需要啟動時饑餓加載。
zuul: ribbon: eager-load: enabled: true
springcloud 中Feign調用常見問題
註: 本文基於Springcloud Edgware版本
一、Feign調用首次失敗問題
1、Feign簡介:
Feign是一個聲明式的偽Http客戶端,它使得寫Http客戶端變得更簡單。使用Feign,隻需要創建一個接口並註解。它具有可插拔的註解特性,可使用Feign 註解和JAX-RS註解,Feign 整合瞭Ribbon。
2、原因分析:
Feign整合Hystrix組件後,Hystrix默認的超時時間是1秒,如果超過這個時間尚未響應,將會進入自定義的fallback代碼,往往首次請求會比較慢(由於Ribbon是懶加載的,在首次請求時,才會開始初始化相關類),這個響應時間可能就大於1秒瞭,出現調用失敗
3、解決方案
(1)增加Hystrix的超時時間,默認為1s
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 10000
(2)配置餓加載(推薦使用)
ribbon: eager-load: clients: project1,project2 enabled: true
(3)禁用Hystrix超時(不推薦使用)
hystrix: command: default: execution: timeout: enabled: false
(4)為fegin全局禁用hystrix(此種方式較為極端,不建議使用)
feign: hystrix: enabled: false
二、Feign整合Hystrix之後日志顯示問題
1、解決方案
Feign整合Hystrix之後,當調用失敗會走fallback邏輯,造成日志不顯示,往往我們需要看日志分析原因,進行故障排查。
(1)在application中配置,開區Feign對Hystrix的支持
feign: hystrix: enabled: true
(2)編寫Feigin的客戶端以及回滾類
在客戶端FeignClient註解配置相對應的回滾類,fallbackFactory = LogFallbackFactory.class,name屬性為註冊中心其他服務的名稱
/** * @description:fegin調用客戶端 * * @author: LUOYUAN * @date: 2019-08-07-10:33 * @function: */ @FeignClient(name = "eureka-log",path = "/api/log",fallbackFactory = LogFallbackFactory.class) public interface LogFeignClient { @RequestMapping(value = "list", method = RequestMethod.GET) public String logList(); }
/** * @description:feign調用失敗邏輯 * @author: LUOYUAN * @date: 2019-08-07-10:34 * @function: */ @Slf4j public class LogFallbackFactory implements FallbackFactory<LogFeignClient> { @Override public LogFeignClient create(Throwable throwable) { return new LogFeignClient() { @Override public String logList() { log.info("query log fallback reason was:",throwable); return null; } }; } }
調用失敗會打印異常信息
query log fallback reason was:
feign.RetryableException: Connection refused: connect executing GET http://eureka-log/api/log/list
at feign.FeignException.errorExecuting(FeignException.java:132)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:113)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)
at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:109)
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302)
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298)
三、Feign調用時定義的fallback不生效
Springcloud Dalston之前得到版本,Feign默認已經開啟瞭Hystrix熔斷器,從Dalaton版本開始,默認關閉Hystrix支持,需手動開啟,在application.yaml中添加如下配置
feign: hystrix: enabled: true
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Feign Client 超時時間配置不生效的解決
- springcloud之Feign超時問題的解決
- SpringCloud微服務基礎簡介
- SpringCloud微服務熔斷器Hystrix使用詳解
- 解決Feign獲取異常信息的處理方案