溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何解決springcloud中Feign超時(shí)的問(wèn)題

發(fā)布時(shí)間:2021-06-24 10:52:55 來(lái)源:億速云 閱讀:396 作者:chen 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要講解了“如何解決springcloud中Feign超時(shí)的問(wèn)題”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“如何解決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ù)客戶端,這便得編寫(xiě)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)

如何解決springcloud中Feign超時(shí)的問(wèn)題

局部配置(就是指定提供者)

#--------------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í)行的代碼

如何解決springcloud中Feign超時(shí)的問(wèn)題

輸出結(jié)果

如何解決springcloud中Feign超時(shí)的問(wèn)題

不是一共重試兩次嗎?這里邊就涉及到了一個(gè)公式

共重試次數(shù) = (MaxAutoRetries+MaxAutoRetriesNextServer+(MaxAutoRetries * MaxAutoRetiresNextServer)
      = 2 + 0 + (2 * 0)
      = 2

在加上我們手動(dòng)請(qǐng)求一次那就是:2 + 1=3次

公式很重要!

感謝各位的閱讀,以上就是“如何解決springcloud中Feign超時(shí)的問(wèn)題”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)如何解決springcloud中Feign超時(shí)的問(wèn)題這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI