当 HTTP 连接池遇上 KeepAlive 时

解决Elasticsearch Connection reset by peer异常 随着ES的密集使用,线上环境,不同应用最近几天陆续有报java.io.IOException: Connection reset by peer异常,感觉不太正常。直接影响就是用户查询或者变更ES数据失败。 阅读详情

点击上方“芋道源码”,选择“置顶公众号”

技术文章第一时间送达!

源码精品专栏

 

来源:http://t.cn/E4J2p8i

  • 1. 连接种类

  • 2 keepalive机制

  • 3. tomcat8对keepalive的实现

  • 4. 连接池对keepalive的处理

  • 5. Connection reset by peer异常

艿艿:看到 Connection reset by peer 异常,会不会头疼???


最近在使用netty作为http客户端通过pool连接tomcat的时候,出现了很多Connection reset by peer 的IOException的异常。便对问题的根源做了细致的调研。

1. 连接种类

一般连接主要分为长连接,短连接和http的keepalive连接。

1.1 长连接:建立完连接后,该连接不再进行释放。

  • 优点

    • 性能较高,不需要重复建立tcp连接或者关闭tcp连接

    • 基本上不会出现CLOSE_WAIT和TIME_WAIT的问题

  • 缺点:一般需要一个连接池来维护长连接(一般有数据库连接池,http的连接池等) 复杂度较高

1.2 短连接:每次请求均需要tcp三次握手建立连接,业务执行,tcp四次挥手关闭连接。

  • 优点:实现简单。

  • 缺点:

    • 性能较差。大部分都是tcp层面上的交互(新建和关闭tcp连接)

    • 系统会出现大量的tcp的状态是:TIME_WAIT 如果没有设置SO_RESUSEADDR ,很容易出现端口被占满的情况。(在关闭完连接时,tcp状态是TIME_WAIT,只有等2个MSL后,才会进行close掉)

1.3 http的keepalive:用于http协议。在http 1.1中,为了解决长连接提出的。

  • 优点:用于维护长连接,提升性能

  • 缺点:需要在header中进行控制,需要交互控制,相对复杂。

2 keepalive机制

提到keepalive, 容易对下面三种机制混淆:

  • keepalived

  • tcp 的 keepalive

  • http 的 keepalive

2.1 keepalived

用途:高可用,一般是和lvs一起使用。

具体可参考:http://outofmemory.cn/wiki/keepalived-configuration

2.2 tcp的keepalive

用途:socket连接的保活。在新建socket的时候,可以设置SO_KEEPALIVE 进行打开。

keepalive主要有三个参数:

  • tcp_keepalive_time: 一个连接需要TCP开始发送keepalive探测数据包之前的空闲时间。以秒为单位

  • tcp_keepalive_probes: 发送TCP keepalive探测数据包的最大数量,默认是9.如果发送9个keepalive探测包后对端仍然没有响应,便发送RST关闭掉连接。

  • tcp_keepalive_intvl: 发送两个TCP keepalive探测数据包的间隔时间,默认是75秒

2.3 http的 keepalive

用途:http的长连接,在http 1.0中使用的为短连接:每一次请求均需要新建tcp连接,http协议数据的发送接收,关闭tcp连接。 该种机制性能很 低,在http 1.1协议中引入了keepalive机制来保持tcp连接。

在http1.0中,全部是短连接,如果想建立长连接,需要在header里面加上keepalive,这样web服务器看到这个字段,不会立马关闭连接。而是将tcp连接维持一段时间。如果需要关闭,则在header中写 keepalive close,来告诉 客户端需要关闭该连接。

在http1.1中,默认会实现keepalive,如果使用的是http1.1协议,header是不需要加上keepalive的。

3. tomcat8对keepalive的实现

3.1 http 1.0实现

tomcat8中,如果发送的是http1.0的协议。 tomcat8返回的均是1.1的协议。并且不管请求的header有没有Connection:keepalive ,均会在返回的header中加上connection:close 。下面是访问tomcat8的截图:

  • GET请求是http 1.0,但是返回的是1.1的协议:

    img
  • 返回的header里面有Connection:close

    img

3.2 http 1.1实现

tomcat8主要有两个参数来控制keepalive的机制。keepAliveTimeout 和maxKeepAliveRequests

  • keepAliveTimeout: 默认和soTimeout 值保持一致,该值为20000ms,也就是在这么长时间内没有通信,tomcat会关闭掉该连接。设置为-1 则代表不会关闭该连接。

  • maxKeepAliveRequests :默认为100,也就是在keepAliveTimeout时间内,如果使用次数超过100,则会关闭掉该连接。设置为-1,则代表不会关闭连接。在关闭后,会在返回的header上面加上Connection:close 。

如果需要tomcat保持长连接:可配置 maxKeepAliveRequests = "-1" keepAliveTimeout=-"-1" ,则tomcat8不会关闭掉该连接。

4. 连接池对keepalive的处理

主要需要处理两个地方:

  • 1:maxKeepAliveRequests 连接达到默认的设置次数。则会在header上面加Connection:close。

    • 在接收web服务器返回的数据时,需要检查一下header里面是否有Connection:close,如果close,则需要将该连接从连接池里物理关闭掉。否则容易出现connection reset by peer的异常。

  • 2:keepAliveTimeout 超过该时间没有流量,则会关闭掉连接。

    • tomcat在连接空闲超过该时间后,会主动关闭掉连接。会向客户端发送FIN命令。

如果是IO(同步socket):则在获取连接的时候需要检查一下该socket的连接状态。 因为tcp在底层已经关闭了该连接。 如果不检查的话,则会SocketCloseException的错误。

如果是NIO(异步channel) :则在selector的时候,read数据的时候,会返回-1,然后将该连接从连接池给物理关闭掉。

5. Connection reset by peer异常

异常场景:

  • 1: 当我们往一个对端已经close的通道写数据的时候,对方的tcp会收到这个报文,并且反馈一个reset报文,当收到reset报文的时候,继续做select读数据的时候就会抛出Connect reset by peer的异常。该异常为jdk抛出的异常。在native代码里面抛出。

  • 2:尝试和未开放的服务器端口建立tcp连接时,服务器tcp将会直接向客户端发送reset报文

  • 3:ack报文丢失,并且超出一定的重传次数或时间后,会主动向对端发送reset报文释放该TCP连接

连接池出现该异常分析:

  • 1:由于客户端在收到Connection:close的header时候并没有物理关闭该连接,而是将该连接返回到了连接池中。

  • 2:下一个请求拿到该连接发送数据,由于tomcat的该socket通道已经关闭,tomcat接收到该连接时,便会回复一个RST。

  • 3:客户端在读取数据(RST的时候,内部会调用(JDK)SocketChannel.read的时候抛出 java.io.IOException(Connection reset by peer)



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:

已在知识星球更新源码解析如下:


此时此刻,我想吟诗一首↓↓↓↓↓

好看好看真好看↓↓

快点快点真快点↓↓

java.io.IOException: Connection reset by peer 完整错误信息: java.io.IOException: Connection reset by peer at sun.nio.ch.FileDispatcherImpl.read0(Native Method) at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39) at sun.nio.ch.IOUtil.r... 阅读详情

相关推荐

当http连接池遇上keepalive

最近在使用netty作为http客户端通过pool连接tomcat的时候,出现了很多Connection reset by peer 的IOException的异常。便对问题的根源做了细致的调研。

hetaohappy的专栏 1万+

Connection reset by peer的常见原因及解决办法

1,如果一端的Socket被关闭(或主动关闭,或因为异常退出而 引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。 Socket默认连接60秒,60秒之内没有进行心跳交互,即读写数据,就会自动关闭连接。 2,一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。 简单的说就是在连接断开后的读和写操作引起的。 Connection reset by peer的常见原因: 1)服务器的

paopaohehe的专栏 12万+

Http连接池PoolingHttpClientConnectionManager的应用

前言 Http连接需要的三次握手开销很大, 传统的HttpURLConnection并不支持连接池, HTTP1.1以上默认开启keepalive, 对于现在springcloud横行的社会, feign可以配置好http连接池, 不过总会有某些个别的接口不在服务中, 还有一些非springboot的老旧项目也要加入cloud大家族中, 对于内部频繁访问的url地址, 这就需要一款量身定做的工具类了. 讲解 先来看看测试效果, 两种工具类的时间消耗对比. 这个是测试用的方法, 前后分别调用了某一接口100

weixin_39417722的博客 1万+

网络:connect reset by peer是怎么回事

我们在做一些应用排查的时候,时常会在日志里看到跟 TCP 有关的报错。比如 connection reset by peer“连接被对端 reset(重置)”,这个字面上的意思是看明白了。要回到这类追问,光靠日志就不行了。事实上,网络分层的好处在于每一层都只要做好自己的事情就可以了。而坏处就比如当前的这种情况:应用层只需要操作系统告诉它:“你的连接层被reset了”。但是为什么会reset呢?...............

OceanStar的博客 10万+

HTTP接口调用时报错 java.io.IOException: Connection reset by peer解决办法

在接口调用时,遇到如下报错:/:?/:?/:?/:?/:?/:?/:?/:?/:?/:?/:?/:?

十三月的博客 4099

SAR成像处理基本知识2——图像尺寸与回波尺寸的关系

阅读本文前,请先了解上一篇文章(SAR成像处理基本知识1——常用专用名词解释) 1. SAR图像尺寸预估方法 以C波段2m@20km的SAR图像为例,假设天线中心下视角为35° ,说明图像尺寸的估计方法。 1.1 距离向尺寸估计 地距分辨率为2m时,距离向分辨率约为1.15m,则要求信号带宽不小于130MHz,假设信号带宽为150MHz,采样率为180MHz,那么距离向分辨单元为0.833m。 地距幅宽为20km时,距离向幅宽约为20*sind(3...

爱学习的小伟的博客 4955

当 HTTP 连接池遇上 KeepAlive:深度解析网络性能优化之道

HTTP连接池与Keep-Alive机制是现代网络应用性能优化的关键技术。连接池通过复用TCP连接减少创建和销毁开销,其核心组件包括连接存储、分配算法和验证策略。Keep-Alive机制则允许单个连接处理多个HTTP请求,在HTTP/1.1中默认启用。两者的协同工作显著提升了性能,连接池管理多个连接,Keep-Alive实现单个连接的复用。 最佳实践包括合理配置连接池参数(如maxTotal、maxPerRoute)、实施连接预热和自适应调优策略。微服务架构中可通过服务网格集中管理连接池,大规模部署时建议采

油墨香^-^的博客 629

Flutter UI代码生成实战:Cursor与MCP的企业级规范适配

本文探讨了在企业级Flutter项目中,如何通过配置Cursor Rules与定制Figma MCP工具,为AI代码生成设定严格的开发规范。该方法解决了AI生成代码与现有项目架构、命名约定及资源引用规范脱节的核心痛点,实现了从Figma设计稿到高质量、可维护Flutter UI代码的自动化流程,显著提升团队协作效率与代码一致性。

http9protocoller的博客 280

http连接池与keepalive

最近在使用netty作为http客户端通过pool连接tomcat的时候,出现了很多Connection reset by peer 的IOException的异常。便对问题的根源做了细致的调研。 1 连接种类      一般连接主要分为长连接,短连接和http的keepalive连接。 1.1 长连接:建立完连接后,该连接不再进行释放。       优点:性能较高,不需要重复建立tcp连...

老猿说说专栏 2384

新疆地形数据下载:30米、12.5米、5米DEM地形数据

新疆是我国陆地面积最大的省级行政区,总面积达166万平方公里。新疆的地形也十分的复杂,新疆的地形呈山脉与盆地相间排列,盆地被高山环抱,,俗称“三山夹两盆”。三山指阿尔泰山、昆仑山、天山,两盆是指塔里木盆地和准噶尔盆地。 对精度要求不高的话,可以直接使用图新地球下载 新疆30米地形数据 大小:9.26GB 来自ASTER v3的新疆30米地形数据 30米地形数据下载 新疆12.5米地形数据 12.5米DEM数据由于精度比较高,一般不会用到全省的数据,通常用的是一个地区的,因此,可以单独分

LocaSpace的博客 3496

【GIS效率手册】告别C盘爆满:三步重置ArcMap默认地理数据库路径

本文针对ArcMap用户C盘空间常被占满的问题,提供了三步重置默认地理数据库路径的详细教程。通过修改地图文档属性,将数据存储位置从C盘迁移至其他驱动器,不仅能有效释放系统盘空间,还能提升数据管理效率与安全性,是GIS数据规范化管理的关键一步。

g2h3i4j5的博客 546

nginx的keepalive和keepalive_requests

当使用nginx作为反向代理时,为了支持长连接,需要做到两点: 从client到nginx的连接是长连接 从nginx到server的连接是长连接 保持和client的长连接: http { keepalive_timeout 120s 120s; keepalive_requests 10000; } keepalive_timeout #语法 keepalive_timeout timeout [header_timeout]; 第一个参数:设置keep-alive客户端连接

奔跑的菜鸡 1万+

基于stm32开发的红外循迹小车

2.L298N电机驱动模块:分别是5V,12V,GND,可以通过外加电源给驱动模块供电,IN1,IN2,IN3,IN4,EN1,EN2,通过给IN口不同的电平,可以达到控制电机正反转,EN口为使能口,可以通过给EN口不同的PWM波,来达到控制小车速度,1.红外循迹模块:检测黑线的原理是向外发射红外线,当没有遇到黑线的时候,返回回来,之后返回高电平,当遇到黑线的时候,红外被吸收,返回高电平,读取相应IO口的电平就可以知道小车此时的大致位置;模块有四个输入接口,分别连接四个TT马达,驱动小车运动;

2301_81374681的博客 1万+

HttpComponents HttpClient连接池(4)-连接的重用和KeepAlive

在上一篇文章里我们介绍了 httpclient 连接池中对于连接的申请和释放,这里我们主要介绍连接的重用,以及 keep alive。http连接的重用在上一篇文章 http 连接的释放...

weixin_46073333的博客 1026

嵌入式设备的switch 以及PHY 芯片调试和选型 (1)

越来越的设备需要多网口的需求,于是需求搭配一个交换机实现网口的扩展。但是很多软件或是硬件工程师在实际选型和应用中经常会遇到一些问题。这里总结一下,避免大家采坑。 几个概念: MAC(介质访问控制),可以理解成数据链路层即可 PHY(物理性),简单理解层转成物理层的连接组件即可 控制接口(MDC/DMIO,I2C,...

睿峰的博客 1万+

【AI技术赋能有限元分析应用实践】Abaqus有限元分析与深度学习结合20个案例与有限元分析数据来源方法说明

结合 Abaqus 和深度学习,数据的获取和处理是关键的一步。通过从仿真、实验、公开数据库或合成数据中获取数据,经过预处理后,可以将其用于训练深度学习模型。最终,将训练好的深度学习模型与 Abaqus 集成,用于材料行为预测、结构优化、非线性分析、损伤预测等任务,从而提升仿真效率和精度。

源代码杀手的博客 3213

nginx keepalive配置详解

Nginx Keepalive配置详解:文章介绍了Nginx中两种Keepalive配置方式 - 客户端Keepalive(keepalive_timeout和keepalive_requests参数)和上游服务器Keepalive(upstream keepalive)。详细说明了各项参数的设置建议、常见问题排查方法以及性能优化技巧,包括合理设置超时时间、请求次数限制和连接池大小。同时提供了完整配置示例、错误排查手段和不同业务场景下的最佳实践方案,帮助管理员根据实际需求优化Nginx长连接配置。

onlymscn的博客 1368

【C#学习记录】如何让界面控件实现自适应布局(Winform)

小伙伴们大家好,我是雷工!在软件界面设计中,客户常常要求设计的界面可以随意缩放,缩放过程中,界面中的按钮等控件也会随着窗体变大缩小自动调整显示位置和尺寸大小。在C#的Winform窗体中如何实现这个效果,下面我们一起学习下。

做有价值的事,积累有价值的笔记! 1万+

golang http client 连接池

转自:http://oohcode.com/2018/06/01/golang-http-client-connection-pool/ golang http client 连接池 2018-06-01 golang标准库net/http做为client时有哪些细节需要注意呢,这里做一个详细的分析。 net/http client工作流程 首先分析一下client的工作流程。 下面...

qq_21514303的博客 1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Nginx-KeepAlive

如果你有任何疑问或想要分享的经验,请在评论区留言交流!

m0_61787196的博客 606

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

tcp keepalive java_TCP keepalive 和 http keep-alive

keepalive机制TCP keepalive概念在使用TCP长连接(复用已建立TCP连接)的场景下,需要对TCP连接进行保活,避免被网关干掉连接。在应用层,可以通过定时发送心跳包的方式实现。而Linux已提供的TCP KEEPALIVE,在应用层可不关心心跳包何时发送、发送什么内容,由OS管理:OS会在该TCP连接上定时发送探测包,探测包既起到连接保活的作用,也能自动检测连接的有效性,并自动关...

weixin_29798625的博客 301

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: 基于 Netty 如何实现高性能的 HTTP Client 的连接池
下一篇: 给你一份长长长的 Spring Boot 知识清单(上)
公众号-芋道源码
博客等级 码龄10年 1636粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值