如何解決springcloud feign 首次調(diào)用100%失敗的問題
敘述
在高并發(fā)情況下發(fā)布應(yīng)用時(shí),經(jīng)常會(huì)發(fā)現(xiàn)監(jiān)控中有很多超時(shí)報(bào)錯(cuò)或者斷路器打開,下圖中可以看到監(jiān)控情況,測(cè)試時(shí)也會(huì)偶現(xiàn)第一次feign調(diào)用出錯(cuò),第二次就會(huì)恢復(fù)正常。

分析
大家都知道,這里feign底層是集成的ribbon,這里ribbon也會(huì)有http連接池,這里的連接池是長(zhǎng)連接,定時(shí)初始化一批并銷毀舊連接,這里還包括一些上下文需要初始化,但是在容器初始化好時(shí),ribbon底層的client是未初始化的,當(dāng)?shù)谝淮握{(diào)用時(shí),有一個(gè)初始化過程會(huì)導(dǎo)致超時(shí),一般情況下會(huì)說需要調(diào)整超時(shí)時(shí)間,但是在電商高并發(fā)情況下,這里肯定時(shí)不現(xiàn)實(shí)的,響應(yīng)請(qǐng)求都需要ms級(jí)別。
解決方案
ribbon饑餓加載
這里可以通過配置ribbon饑餓加載來減少出錯(cuò)次數(shù),如下:
ribbon:
# 饑餓加載
eager-load:
# 是否開啟饑餓加載
enabled: true
# 饑餓加載的服務(wù)
clients: demo-goods,demo-product
這里為什么說不能完全解決呢?因?yàn)樵诎l(fā)布時(shí)流量切換的瞬間,流量太大,并不是僅僅ribbon需要初始化,hystrix、web容器線程池等都需要初始化或者擴(kuò)容,這里也需要耗時(shí),所以這里的饑餓加載僅僅只是做到了發(fā)布時(shí)減少錯(cuò)誤數(shù)。
zuul饑餓加載
網(wǎng)關(guān)作為對(duì)外請(qǐng)求的入口,zuul內(nèi)部使用Ribbon調(diào)用其他服務(wù),Spring Cloud默認(rèn)在第一次調(diào)用時(shí)懶加載Ribbon客戶端。zuul同樣需要維護(hù)一個(gè)相對(duì)的子應(yīng)用環(huán)境的上下文,所以也需要啟動(dòng)時(shí)饑餓加載。
zuul:
ribbon:
eager-load:
enabled: true
springcloud 中Feign調(diào)用常見問題
注: 本文基于Springcloud Edgware版本
一、Feign調(diào)用首次失敗問題
1、Feign簡(jiǎn)介:
Feign是一個(gè)聲明式的偽Http客戶端,它使得寫Http客戶端變得更簡(jiǎn)單。使用Feign,只需要?jiǎng)?chuàng)建一個(gè)接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解,F(xiàn)eign 整合了Ribbon。
2、原因分析:
Feign整合Hystrix組件后,Hystrix默認(rèn)的超時(shí)時(shí)間是1秒,如果超過這個(gè)時(shí)間尚未響應(yīng),將會(huì)進(jìn)入自定義的fallback代碼,往往首次請(qǐng)求會(huì)比較慢(由于Ribbon是懶加載的,在首次請(qǐng)求時(shí),才會(huì)開始初始化相關(guān)類),這個(gè)響應(yīng)時(shí)間可能就大于1秒了,出現(xiàn)調(diào)用失敗
3、解決方案
(1)增加Hystrix的超時(shí)時(shí)間,默認(rèn)為1s
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 10000
(2)配置餓加載(推薦使用)
ribbon:
eager-load:
clients: project1,project2
enabled: true
(3)禁用Hystrix超時(shí)(不推薦使用)
hystrix:
command:
default:
execution:
timeout:
enabled: false
(4)為fegin全局禁用hystrix(此種方式較為極端,不建議使用)
feign: hystrix: enabled: false
二、Feign整合Hystrix之后日志顯示問題
1、解決方案
Feign整合Hystrix之后,當(dāng)調(diào)用失敗會(huì)走fallback邏輯,造成日志不顯示,往往我們需要看日志分析原因,進(jìn)行故障排查。
(1)在application中配置,開區(qū)Feign對(duì)Hystrix的支持
feign:
hystrix:
enabled: true
(2)編寫Feigin的客戶端以及回滾類
在客戶端FeignClient注解配置相對(duì)應(yīng)的回滾類,fallbackFactory = LogFallbackFactory.class,name屬性為注冊(cè)中心其他服務(wù)的名稱
/**
* @description:fegin調(diào)用客戶端
*
* @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調(diào)用失敗邏輯
* @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;
}
};
}
}
調(diào)用失敗會(huì)打印異常信息
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調(diào)用時(shí)定義的fallback不生效
Springcloud Dalston之前得到版本,F(xiàn)eign默認(rèn)已經(jīng)開啟了Hystrix熔斷器,從Dalaton版本開始,默認(rèn)關(guān)閉Hystrix支持,需手動(dòng)開啟,在application.yaml中添加如下配置
feign:
hystrix:
enabled: true
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot項(xiàng)目通過redis實(shí)現(xiàn)接口的冪等性
這篇文章主要為大家介紹了Springboot項(xiàng)目通過redis實(shí)現(xiàn)接口的冪等性,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
Java實(shí)現(xiàn)Promise.all()的示例代碼
這篇文章主要介紹了Java實(shí)現(xiàn)Promise.all()的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08
Spring中的HandlerMapping執(zhí)行流程詳解
這篇文章主要介紹了Spring中的HandlerMapping執(zhí)行流程詳解,HandlerMapping在Spring MVC框架的jar包下面,他是處理映射器,為用戶發(fā)送的請(qǐng)求找到合適的Handler Adapter,它將會(huì)把請(qǐng)求映射為HandlerExecutionChain對(duì)象,需要的朋友可以參考下2023-08-08
RocketMQ重試機(jī)制及消息冪代碼實(shí)例解析
這篇文章主要介紹了RocketMQ重試機(jī)制及消息冪代碼實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
Java去重排序之Comparable與Comparator的使用及說明
這篇文章主要介紹了Java去重排序之Comparable與Comparator的使用及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
Mybatis-Plus自動(dòng)填充更新操作相關(guān)字段的實(shí)現(xiàn)
數(shù)據(jù)庫(kù)表中應(yīng)該都要有create_time、update_time字段;那么在開發(fā)中,對(duì)于這些共有字段的處理應(yīng)該要進(jìn)行統(tǒng)一,這樣就可以簡(jiǎn)化我們的開發(fā)過程。那么本文就對(duì)Mybatis-Plus中的字段自動(dòng)填充進(jìn)行記錄2021-11-11
SpringCloud Finchley Gateway 緩存請(qǐng)求Body和Form表單的實(shí)現(xiàn)
在接入Spring-Cloud-Gateway時(shí),可能有需求進(jìn)行緩存Json-Body數(shù)據(jù)或者Form-Urlencoded數(shù)據(jù)的情況。這篇文章主要介紹了SpringCloud Finchley Gateway 緩存請(qǐng)求Body和Form表單的實(shí)現(xiàn),感興趣的小伙伴們可以參考一下2019-01-01
Java動(dòng)態(tài)初始化數(shù)組,元素默認(rèn)值規(guī)則詳解
動(dòng)態(tài)初始化數(shù)組涉及先定義數(shù)組長(zhǎng)度,后填充具體數(shù)據(jù),適用于數(shù)據(jù)量已知但具體值未定的情況,這種初始化方式允許程序運(yùn)行過程中賦值,并會(huì)根據(jù)數(shù)據(jù)類型設(shè)定默認(rèn)值,如整型為0,字符串為null,動(dòng)態(tài)初始化與靜態(tài)初始化格式不能混用2024-10-10

