问题描述:open feign配置OKhttp调用远程API,连续调用次数较少时,一切正常,次数非常多时(例如,连续请求600次)就抛出java.net.SocketTimeoutException: timeout,关键信息如下:

Caused by: java.net.SocketTimeoutException: timeout
at okhttp3.internal.http2.Http2Stream$StreamTimeout.newTimeoutException(Http2Stream.kt:662)
at okhttp3.internal.http2.Http2Stream$StreamTimeout.exitAndThrowIfTimedOut(Http2Stream.kt:671)
at okhttp3.internal.http2.Http2Stream$FramingSource.read(Http2Stream.kt:377)
at okhttp3.internal.connection.Exchange$ResponseBodySource.read(Exchange.kt:279)
at okio.RealBufferedSource.read(RealBufferedSource.kt:41)
at okio.RealBufferedSource.exhausted(RealBufferedSource.kt:51)
at okio.InflaterSource.refill(InflaterSource.kt:94)
at okio.InflaterSource.read(InflaterSource.kt:54)
at okio.GzipSource.read(GzipSource.kt:69)
at okio.RealBufferedSource$inputStream$1.read(RealBufferedSource.kt:438)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at java.io.PushbackInputStream.read(PushbackInputStream.java:186)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.Reader.read(Reader.java:140)
at org.springframework.util.StreamUtils.copyToString(StreamUtils.java:91)
at org.springframework.http.converter.StringHttpMessageConverter.readInternal(StringHttpMessageConverter.java:96)
at org.springframework.http.converter.StringHttpMessageConverter.readInternal(StringHttpMessageConverter.java:44)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:199)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:114)
... 15 common frames omitted

使用spring java config 进行局部属性配置,OKhttp基本配置代码如下所示:

/**
* @author 楼兰胡杨
*/
public class FeignConfig { private final static int READ_TIMEOUT = 10;
private final static int MAX_IDLE_CONNECTIONS = 200;
private final static int CONNECT_TIMEOUT = 30;
private final static int WRITE_TIMEOUT = 35; /**
* 客户端配置
*
*/
@Bean
public OkHttpClient okHttpClient() {
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
//读取超时时间
clientBuilder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
//连接超时时间
clientBuilder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);
//写入超时时间
clientBuilder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS); //默认最大5个空闲连接
clientBuilder.connectionPool(new ConnectionPool(MAX_IDLE_CONNECTIONS, READ_TIMEOUT, TimeUnit.MINUTES)); return clientBuilder.build();
}
}

  FeignConfig类上切勿添加@Component注解,一旦添加,它将变成全局配置,这里只用作局部配置。当然,我们在yaml配置文件中已经开启了OKhttp支持:

# 默认关闭,现开启
feign.okhttp.enabled=true

由@FeignClient注解的configuration属性配置这个API接口类的特殊属性,如果是全局配置,则不需要有configuration指定配置类。eign client代码如下:

@FeignClient(name = "feignApi", url = "${self.your.url}", configuration = FeignConfig.class)
public interface FeignApiClient { @PostMapping(value = "/xxx")
String query(@RequestBody ParamDTO dto); }

问题分析:连续请求次数比较少时,一切正常,说明配置OKhttp基本配置没有问题,而连续请求次数非常多(例如600+次)时就出问题,说明TCP连接时间超过了对方TCP长连接有效期,导致抛出异常。

解决办法把TCP长连接改为短连接,设置headers 属性 {"Connection=close"}。不论客户端还是服务端的header,只要包含了值为close的connection,都表明当前正在使用的TCP连接在本次请求处理完毕后会被断掉,以后客户端再进行请求时,就必须创建新的TCP连接,而非复用,从而避开TCP长连接有效期的约束。优化后,query函数代码如下:

@FeignClient(name = "feignApi", url = "${self.your.url}", configuration = FeignConfig.class)
public interface FeignApiClient {
@PostMapping(value = "/xxx", headers = {"Connection=close"})
String query(@RequestBody ParamDTO dto); }

  关于TCP长连接和短连接的介绍,请戳《http协议中长连接和短连接介绍》。 老铁们, 因个人能力有限,难免有瑕疵,如果发现bug或者有更好的建议,那么请在文章下方留言!

@FeignClient注解配置局部超时时间、OkHttp长连接和SocketTimeoutException异常解决办法的更多相关文章

  1. WCF服务运行一段时间后客户端无法连接WCF服务的解决办法 (转)

    WCF服务运行一段时间后客户端无法连接WCF服务的解决办法 (转) Windows Communication Foundation (WCF)是Microsoft为构建面向服务的应用提供的分布式通信 ...

  2. 【已解决】HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法

    [问题] 用C#模拟网页登陆,其中去请求几个页面,会发起对应的http的请求request,其中keepAlive设置为true,提交请求后,然后会有对应的response: resp = (Http ...

  3. mybatis配置sql超时时间

    mybatis如果不配置,默认超时时间是不做限制的.当系统慢sql很多时,势必会增加数据库压力,系统性能及稳定性降低.所以有必要要设置sql超时设置,下面配置超时时间是5分钟. 第一步:全局配置如下 ...

  4. config文件中可以配置查询超时时间

    web.config配置数据库连接 第一种:获取连接字符串 首先要定义命名空间 system.configuration 1.  string connstr= string constr = Con ...

  5. 关于dubbo的provider和consumer都配置timeout超时时间的情况

    本文转自:http://blog.csdn.net/lkforce/article/details/54380201 前言 在dubbo的provider和consumer的配置文件中,如果都配置了t ...

  6. Spring MVC前台使用html页面作为视图,配置静态资源后Controller控制器不起作用的解决办法

    1.Spring MVC搭建项目的时候,想使用html页面作为前端的视图,你会发现html页面不能访问,原因是由于Spring拦截器将其拦截寻找控制器的缘故,解决办法就是配置静态资源: <mvc ...

  7. Echarts 折线图y轴标签值太长时显示不全的解决办法

    问题 分析 解决办法 问题 先看一下正常的情况 再看一下显示不全的情况 所有的数据都是从后台取的,也就是说动态变化的,一开始的时候数据量不大不会出现问题,后面y轴的值越来越大的时候就出现了这个显示不全 ...

  8. HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法

    [问题] 用C#模拟网页登陆,其中去请求几个页面,会发起对应的http的请求request,其中keepAlive设置为true,提交请求后,然后会有对应的response: resp = (Http ...

  9. 【转载】HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法

    [问题] 用C#模拟网页登陆,其中去请求几个页面,会发起对应的http的请求request,其中keepAlive设置为true,提交请求后,然后会有对应的response: resp = (Http ...

  10. 自定义配置文件读取产生的“无法添加已属于该配置的 ConfigurationSection”异常解决办法

    最近在编写一个读写自定义配置文件的功能时遇到一个问题,在初始化的时候读入配置显示出来,修改后把配置回存到配置文件,在回存的时候,先移除配置节,再添加,在添加的时候遇到如下的异常: {"无法添 ...

随机推荐

  1. 基于融合语义信息改进的内容推荐算法。Improved content recommendation algorithm integrating semantic information

    引言 路漫漫其修远兮,吾将上下而求索.每天一篇论文,做更好的自己. 本文读的这篇论文为发表于2023年5月28日的一篇名为<基于融合语义信息改进的内容推荐算法>(基于融合语义信息改进的内容 ...

  2. manim边学边做--场景Scene简介

    在 Manim 社区版本中,Scene(场景)是构建动画的核心概念之一,它为我们提供了一个结构化的方式来组织和呈现动画内容. 本文将介绍什么是Scene,它在Manim动画中的作用,以及不同类型的Sc ...

  3. 宝塔导入mysql数据库后,phpmyadmin可以登录,本地Navicat无法登录

    问题描述:宝塔导入mysql数据库后,phpmyadmin可以登录,本地Navicat无法登录 问题排查:1.检查服务器3306端口是否开启,如果为云服务器,需要登录云服务器后台安全组设置开启: 2. ...

  4. 最新版 Proteus 8.15 Professional 图文安装教程(附安装包)

    前言 大家好,我是梁国庆. Proteus 是世界上唯一将电路仿真软件.PCB设计软件和虚拟模型仿真软件三合一的设计平台. 本篇博主将手把手带领大家安装最新版 Proteus 8.15. 若图片加载超 ...

  5. nnUNet相关方法

  6. 本地如何访问vue2 生成的dist代码

    前言 当你使用 Vue CLI 或其他构建工具构建 Vue 2 项目时,它会生成一个 dist 文件夹,这个文件夹包含了你项目的生产环境版本的静态资源文件(HTML.JavaScript 和 CSS) ...

  7. The selected directory is not a valid home for Go SDK

    前言 The selected directory is not a valid home for Go SDK 出现这个错误的原因是 idea 的 Go-plugin 插件,和 Go 的sdk版本不 ...

  8. 解决Oracle锁表情况

    在使用Oracle数据库更新数据的时候,有两种查询方式可以修改编辑数据: select t.*,t.rowid from table t select * from table for update ...

  9. OpenAI的GPT-4o:普通人的AI秘书来了

    1. 惊艳时刻:AI比你想象的更"人性" 早餐时,张三正埋头刷推送,一篇关于OpenAI发布GPT-4o的文章瞬间点燃了他的好奇心.这个AI简直是科技圈的惊雷!竟然可以像真人一样说 ...

  10. 分布式任务调度系统 xxl-job

    微服务难不难,不难!无非就是一个消费方,一个生产方,一个注册中心,然后就是实现一些微服务,其实微服务的难点在于治理,给你一堆 微服务,如何来管理?这就有很多方面了,比如容器化,服务间通信,服务上下线发 ...