springcloud之Feign超時(shí)問(wèn)題的解決
問(wèn)題背景
最近公司項(xiàng)目有個(gè)功能需進(jìn)行三層Feign調(diào)用,且還要調(diào)外部接口,延遲挺大,造成Feign一直提示Read timed out executing POST。
feign.RetryableException: Read timed out executing POST http://****** at feign.FeignException.errorExecuting(FeignException.java:67) at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:104) at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76) at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) at com.sun.proxy.$Proxy113.getBaseRow(Unknown Source) Caused by: java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:170) at java.net.SocketInputStream.read(SocketInputStream.java:141) at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) at java.io.BufferedInputStream.read1(BufferedInputStream.java:286) at java.io.BufferedInputStream.read(BufferedInputStream.java:345) at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:704) at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647) at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1569) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474) at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) at feign.Client$Default.convertResponse(Client.java:152) at feign.Client$Default.execute(Client.java:74)
解決方案
首先,我們看下Feign的簡(jiǎn)介
Feign 是一個(gè)聲明式的web服務(wù)客戶端,這便得編寫web服務(wù)客戶端更容易,使用Feign 創(chuàng)建一個(gè)接口并對(duì)它進(jìn)行注解,它具有可插拔的注解支持包括Feign注解與JAX-RS注解,F(xiàn)eign還支持可插拔的編碼器與解碼器,Spring Cloud 增加了對(duì) Spring MVC的注解,Spring Web 默認(rèn)使用了HttpMessageConverters, Spring Cloud 集成 Ribbon 和 Eureka 提供的負(fù)載均衡的HTTP客戶端 Feign.
這么說(shuō)吧,F(xiàn)eign接口調(diào)用分兩層,Ribbon的調(diào)用和Hystrix調(diào)用,理論上設(shè)置Ribbon的時(shí)間即可,但是Ribbon的超時(shí)時(shí)間和Hystrix的超時(shí)時(shí)間需要結(jié)合起來(lái),按照木桶原則最低的就是Feign的超時(shí)時(shí)間,建議最好配置超時(shí)時(shí)間一致。經(jīng)過(guò)配置一下application設(shè)置后,完美解決了問(wèn)題。因?yàn)榈谌浇涌谥行枰?~20秒不等的時(shí)間,所以這個(gè)數(shù)值也是根據(jù)自己的業(yè)務(wù)系統(tǒng)情況設(shè)置的。
application.xml
#hystrix的超時(shí)時(shí)間 hystrix: command: default: execution: timeout: enabled: true isolation: thread: timeoutInMilliseconds: 30000 #ribbon的超時(shí)時(shí)間 ribbon: ReadTimeout: 30000 ConnectTimeout: 30000
springcloud之Feign 負(fù)載均衡請(qǐng)求超時(shí)時(shí)間
SpringCloud:Greenwich.SR4
SpringBoot:2.1.9.RELEASE
Feign調(diào)用服務(wù)的默認(rèn)時(shí)長(zhǎng)是1秒鐘,也就是如果超過(guò)1秒沒(méi)連接上或者超過(guò)1秒沒(méi)響應(yīng),那么會(huì)相應(yīng)的報(bào)錯(cuò)。
但是在實(shí)際的業(yè)務(wù)中,我們的服務(wù)可能因?yàn)樘貏e原因(網(wǎng)絡(luò)、處理壓力大等)導(dǎo)致相應(yīng)速度超過(guò)1秒鐘,那么就會(huì)報(bào)錯(cuò),下面我們就來(lái)處理如何手動(dòng)配置Feigin的負(fù)載均衡超時(shí)等參數(shù)
全局配置
SpringCloud負(fù)載均衡底層用的就是Ribbon
#--------------Feign負(fù)載均衡配置 配置全局超時(shí)時(shí)間 ribbon: ConnectTimeout: 5000 #請(qǐng)求連接的超時(shí)時(shí)間,默認(rèn)時(shí)間為1秒 ReadTimeout: 5000 #請(qǐng)求處理的超時(shí)時(shí)間
5秒沒(méi)有響應(yīng)成功就報(bào)如下錯(cuò)誤(真實(shí)情況下,會(huì)比5s多一些,因?yàn)榘l(fā)送請(qǐng)求也需要時(shí)間的,模擬超時(shí)可以在請(qǐng)求處理的方法上用Thread.sleep()設(shè)置休眠時(shí)間超過(guò)5s)
局部配置(就是指定提供者)
#--------------Feign負(fù)載均衡配置 局部配置超時(shí)時(shí)間等 feign-product-provider: #指定配置的服務(wù)名稱 ribbon: OkToRetryOnAllOperations: true # 對(duì)所有請(qǐng)求都進(jìn)行重試 MaxAutoRetries: 2 # 對(duì)當(dāng)前實(shí)例的重試次數(shù) MaxAutoRetriesNextServer: 0 # 切換實(shí)例的重試次數(shù)(集群狀態(tài)下,其它對(duì)其它實(shí)例服務(wù)重試的次數(shù)) ConnectTimeout: 3000 # 請(qǐng)求連接的超時(shí)時(shí)間 ReadTimeout: 3000 # 請(qǐng)求處理的超時(shí)時(shí)間
上述提到的服務(wù)名稱如下配置
spring: application: name: feign-product-provider # 隨意設(shè)置
執(zhí)行的代碼
輸出結(jié)果
不是一共重試兩次嗎?這里邊就涉及到了一個(gè)公式
共重試次數(shù) = (MaxAutoRetries+MaxAutoRetriesNextServer+(MaxAutoRetries * MaxAutoRetiresNextServer)
= 2 + 0 + (2 * 0)
= 2
在加上我們手動(dòng)請(qǐng)求一次那就是:2 + 1=3次
公式很重要!
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
一篇文章帶你了解Java容器,面板及四大布局管理器應(yīng)用
這篇文章主要介紹了JAVA布局管理器與面板組合代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-08-08idea注入mapper報(bào)錯(cuò)報(bào)紅的幾種解決方案
相信大家在使用idea的時(shí)候一定會(huì)遇到這樣的問(wèn)題,就是在service里注入mapper的時(shí)候,明明代碼沒(méi)有問(wèn)題,也可以運(yùn)行,但是idea它就是給你報(bào)個(gè)錯(cuò),有個(gè)紅色的波浪線在下面,所以本文將給大家介紹了idea注入mapper報(bào)錯(cuò)報(bào)紅的幾種解決方案,需要的朋友可以參考下2023-12-12mybatis主從表關(guān)聯(lián)查詢,返回對(duì)象帶有集合屬性解析
這篇文章主要介紹了mybatis主從表關(guān)聯(lián)查詢,返回對(duì)象帶有集合屬性解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03FastJson對(duì)于JSON格式字符串、JSON對(duì)象及JavaBean之間的相互轉(zhuǎn)換操作
這篇文章主要介紹了FastJson對(duì)于JSON格式字符串、JSON對(duì)象及JavaBean之間的相互轉(zhuǎn)換,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-11-11Java笛卡爾積算法原理與實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Java笛卡爾積算法原理與實(shí)現(xiàn)方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了笛卡爾積算法的原理及java定義與使用笛卡爾積算法的相關(guān)操作技巧,需要的朋友可以參考下2017-12-12解決MybatisPlus批量插入數(shù)據(jù)報(bào)錯(cuò):Error getting generated 
在使用MybatisPlus進(jìn)行批量插入數(shù)據(jù)時(shí)遇到空指針異常錯(cuò)誤,分析原因是由于主鍵生成策略導(dǎo)致的,嘗試通過(guò)設(shè)置useGeneratedKeys屬性解決問(wèn)題,但因批量插入方法限制,該方法未能成功,最終通過(guò)自定義mapper方法實(shí)現(xiàn)批量插入,解決了問(wèn)題2024-09-09一分鐘掌握J(rèn)ava?Quartz定時(shí)任務(wù)
這篇文章主要為大家介紹了Java?Quartz定時(shí)任務(wù)一分鐘掌握教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05SpringBoot實(shí)現(xiàn)Word轉(zhuǎn)PDF和TXT的實(shí)踐分享
研發(fā)工作中難免會(huì)遇到一些奇奇怪怪的需求,就比如最近,客戶提了個(gè)新需求:上傳一個(gè)WORD文檔,要求通過(guò)系統(tǒng)把該文檔轉(zhuǎn)換成PDF和TXT,所以本文給大家分享了SpringBoot實(shí)現(xiàn)Word轉(zhuǎn)PDF和TXT的實(shí)踐,感興趣的朋友可以參考下2024-08-08