springcloud之Feign超时问题的解决

网友投稿 535 2023-01-03

springcloud之Feign超时问题的解决

问题背景

最近公司项目有个功能需进行三层Feign调用,且还要调外部接口,延迟挺大,造成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.http.HttpClient.parseHTTPHeader(HttpClient.java:704)

at sun.net.http.HttpClient.parseHTTP(HttpClient.java:647)

at sun.net.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1569)

at sun.net.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)

解决方案

首先,我们看下FeigaYmpUERbJn的简介

Feign 是一个声明式的web服务客户端,这便得编写web服务客户端更容易,使用Feign 创建一个接口并对它进行注解,它具有可插拔的注解支持包括Feign注解与JAX-RS注解,Feign还支持可插拔的编码器与解码器,Spring Cloud 增加了对 Spring MVC的注解,Spring Web 默认使用了HttpMessageConverters, Spring Cloud 集成 Ribbon 和 Eureka 提供的负载均衡的HTTP客户端 Feign.

这么说吧,Feign接口调用分两层,Ribbon的调用和Hystrix调用,理论上设置Ribbon的时间即可,但是Ribbon的超时时间和Hystrix的超时时间需要结合起来,按照木桶原则最低的就是Feign的超时时间,建议最好配置超时时间一致。经过配置一下application设置后,完美解决了问题。因为第三方接口中需要3~20秒不等的时间,所以这个数值也是根据自己的业务系统情况设置的。

application.xml

#hystrix的超时时间

hystrix:

command:

default:

execution:

timeout:

enabled: true

isolation:

thread:

timeoutInMilliseconds: 30000

#ribbon的超时时间

ribbon:

ReadTimeout: 30000

ConnectTimeout: 30000

springcloud之Feign 负载均衡请求超时时间

SpringCloud:Greenwich.SR4

SpringBoot:2.1.9.RELEASE

Feign调用服务的默认时长是1秒钟,也就是如果超过1秒没连接上或者超过1秒没响应,那么会相应的报错。

但是在实际的业务中,我们的服务可能因为特别原因(网络、处理压力大等)导致相应速度超过1秒钟,那么就会报错,下面我们就来处理如何手动配置Feigin的负载均衡超时等参数

全局配置

SpringCloud负载均衡底层用的就是Ribbon

#--------------Feign负载均衡配置 配置全局超时时间

ribbon:

ConnectTimeout: 5000 #请求连接的超时时间,默认时间为1秒

ReadTimeout: 5000 #请求处理的超时时间

5秒没有响应成功就报如下错误(真实情况下,会比5s多一些,因为发送请求也需要时间的,模拟超时可以在请求处理的方法上用Thread.sleep()设置休眠时间超过5s)

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

#--------------Feign负载均衡配置 局部配置超时时间等

feign-product-provider: #指定配置的服务名称

ribbon:

OkToRetryOnAllOperations: true # 对所有请求都进行重试

MaxAutoRetries: 2 # 对当前实例的重试次数

MaxAutoRetriesNextServer: 0 # 切换实例的重试次数(集群状态下,其它对其它实例服务重试的次数)

ConnectTimeout: 3000 # 请求连接的超时时间

ReadTimeout: 3000 # 请求处理的超时时间

上述提到的服务名称如下配置

spring:

application:

name: feign-product-provider # 随意设置

执行的代码

输出结果

不是一共重试两次吗?这里边就涉及到了一个公式

共重试次数 = (MaxAutoRetries+MaxAutoRetriesNextServer+(MaxAutoRetries * MaxAutoRetiresNextServer)

      = 2 + 0 + (2 * 0)

      = 2

在加上我们手动请求一次那就是:2 + 1=3次

公式很重要!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:速通快递物流查询单号(速通快递物流查询单号查询官网)
下一篇:如何获得网站api接口(如何获得网站api接口信息)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~