Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >当 HTTP 连接池遇上 KeepAlive 时

当 HTTP 连接池遇上 KeepAlive 时

作者头像
芋道源码
发布于 2018-12-29 03:43:21
发布于 2018-12-29 03:43:21
2.4K0
举报
文章被收录于专栏:芋道源码1024芋道源码1024

来源: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)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 芋道源码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
HTTP 与 TCP 的 KeepAlive 是一个东西吗?
KeepAlive 已经不是什么新鲜的概念了,HTTP 协议中有 KeepAlive 的概念,TCP 协议中也有 KeepAlive 的概念。二者的作用是不同的。本文将详细的介绍 HTTP 中的 KeepAlive,介绍 Tomcat 在 Server 端是如何对 KeepAlive 进行处理,以及 JDK 对 HTTP 协议中 KeepAlive 的支持。同时会详细介绍 TCP 中的 KeepAlive 机制以及应用层的心跳。
涤生
2019/07/10
1.6K0
详解HTTP 与TCP中Keep-Alive机制的区别
keepalive已经不是什么新鲜的概念了,HTTP协议中有keep-alive的概念,TCP协议中也有keep-alive的概念。二者的作用是不同的。本文将详细的介绍http中的keep-alive,介绍tomcat在server端是如何对keep-alive进行处理,以及jdk对http协议中keep-alive的支持。同时会详细介绍tcp中的keepalive机制以及应用层的心跳。
田守枝
2019/05/21
4.1K0
详解HTTP 与TCP中Keep-Alive机制的区别
Linux TCP RST情况
导读 导致“Connection reset”的原因是服务器端因为某种原因关闭了Connection,而客户端依然在读写数据,此时服务器会返回复位标志“RST”,然后此时客户端就会提示“java.net.SocketException: Connection reset”。可能有同学对复位标志“RST”还不太了解,这里简单解释一下:
PHP开发工程师
2021/05/11
6K0
Linux TCP RST情况
nginx优化之keepalive
1、TCP_NODELAY 你怎么可以强制 socket 在它的缓冲区里发送数据? 一个解决方案是 TCP 堆栈的 TCP_NODELAY选项。这样就可以使缓冲区中的数据立即发送出去。
sunsky
2020/08/20
1.3K0
Http 持久连接与 HttpClient 连接池
HTTP协议是无状态的协议,即每一次请求都是互相独立的。因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接。
用户1257393
2018/07/30
2.1K0
Http 持久连接与 HttpClient 连接池
tomcat大量time wait问题
在服务端访问量大的时候检测到大量的time wait,并且接口请求延时较高。 执行 netstat -n |awk ‘/^tcp/{++S[$NF]}END{for(m in S) print m,S[m]}’ 这个shell命令的意思是把netstat -n 后结果的最后一条放到S[]数组中,如果相同则执行+1操作。 此时能看到TCP各种状态下的连接数量,示例
全栈程序员站长
2022/08/14
1.1K0
tomcat大量time wait问题
最近学习了 HTTP 连接池
6.1大促值班发现的一个问题,一个rpc接口在0~2点用户下单高峰的时候表现rt高(超过1s,实际上针对性优化过的接口rt超过这个值也是有问题的,通常rpc接口里面即使逻辑复杂,300ms应该也搞定了),可以理解,但是在4~5点的时候接口的tps已经不高了,耗时依然在600ms~700ms之间就不能理解了。
芋道源码
2020/02/20
1.5K0
最近学习了 HTTP 连接池
HTTP1.1 Keep-Alive到底算不算长连接?
在基础架构部浸润了半年,有一些认知刷新想和童靴们交代一下, 不一定全面,仅代表此时的认知, 也欢迎筒靴们提出看法。
有态度的马甲
2021/11/25
1.5K0
HTTP1.1 Keep-Alive到底算不算长连接?
TCP 的 Keepalive 和 HTTP 的 Keep-Alive 是一个东西吗?
HTTP 的 Keep-Alive,是由应用层(用户态) 实现的,称为 HTTP 长连接; TCP 的 Keepalive,是由 TCP 层(内核态) 实现的,称为 TCP 保活机制;
IT运维技术圈
2022/10/24
1.4K0
nginx,ingress-nginx日常维护及报错
readv() failed (104: Connection reset by peer) while reading upstream
iginkgo18
2021/10/10
12.9K0
Nginx反向代理时保持长连接
HTTP1.1之后,HTTP协议支持持久连接,也就是长连接,优点在于在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。
星哥玩云
2022/07/28
3.2K0
TCP?HTTP? 不同类型探测的引发的坑
nginx-gateway部署在公有云 A, 业务测试服务器部署在办公区机房B, 公有云region A 和 办公区机房 B通过soft V**互连。B机房中有不同类型的应用服务器【nodejs,java(tomcat)】做nginx-gateway的后端upstream节点。nginx-gateway编译安装了ngx_http_upstream_check_module插件,ngx_http_upstream_check_module用于做后端upstream节点的健康监测, healthcheck为每个upstream的后端节点配置有一个raise_counts/fall_couts状态的计数器。业务方同事反馈:从外部访问内部某些应用有概率出现超时, 经观察, nodejs,java(tomcat)的raise_counts计数器概率性地重置为0,
richard.xia_志培
2022/06/14
9870
TCP?HTTP? 不同类型探测的引发的坑
一篇搞懂TCP、HTTP、Socket、Socket连接池
前言:作为一名开发人员我们经常会听到HTTP协议、TCP/IP协议、UDP协议、Socket、Socket长连接、Socket连接池等字眼,然而它们之间的关系、区别及原理并不是所有人都能理解清楚,这篇文章就从网络协议基础开始到Socket连接池,一步一步解释他们之间的关系。
数澜科技
2019/10/17
2.4K0
nginx反向代理时保持长连接
深入了解nginx,get到nginx的一些性能优化方向。除了了解如何保持长连接,也通过本案例学习到开源中间件的一些常用定位思路和优化方法。
京东技术
2021/06/09
9.2K0
gRPC 网关,针对 HTTP 2.0 长连接性能优化,提升吞吐量
简单看下即可,由于含有定制化业务背景,架构图看不懂也没关系,后面我会对里面的核心技术点单独剖析讲解
微观技术
2021/07/05
4.2K0
一篇搞懂TCP、HTTP、Socket、Socket连接池
前言:作为一名开发人员我们经常会听到HTTP协议、TCP/IP协议、UDP协议、Socket、Socket长连接、Socket连接池等字眼,然而它们之间的关系、区别及原理并不是所有人都能理解清楚,这篇文章就从网络协议基础开始到Socket连接池,一步一步解释他们之间的关系。
用户8568307
2022/03/14
1.9K0
一篇搞懂TCP、HTTP、Socket、Socket连接池
又见KeepAlive
最近工作中遇到一个问题,想把它记录下来,场景是这样的: 从上图可以看出,用户通过Client访问的是LVS的VIP, VIP后端挂载的RealServer是Nginx服务器。 Client可以是浏览器
小小科
2018/05/04
1.7K0
又见KeepAlive
Nginx之keepalive解读
keepalive是HTTP/1.1协议中的一个特性,它允许客户端和服务器之间的TCP连接在一个HTTP请求/响应周期结束后保持打开状态,以便在后续的请求中重复使用。这样可以减少TCP连接的建立和关闭次数,从而提高性能。
一个风轻云淡
2023/09/19
1K0
分析 HTTP,TCP 的长连接和短连接以及 sock
HTTP 的长连接和短连接本质上是 TCP 长连接和短连接。HTTP 属于应用层协议,在传输层使用 TCP 协议,在网络层使用 IP 协议。IP 协议主要解决网络路由和寻址问题,TCP 协议主要解决如何在 IP 层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。TCP 有可靠,面向连接的特点。
杰哥的IT之旅
2020/06/18
4.8K0
分析 HTTP,TCP 的长连接和短连接以及 sock
探寻HTTP网络超时的背后真凶:拨开云雾的生产环境排查之旅
场景:公司对外网关对很多外部商户开放,运行多年一直正常,昨天某一个客户调用我们接口的时候频繁报connectiontimeout,异常如下:
用户2781897
2019/05/20
1.7K0
探寻HTTP网络超时的背后真凶:拨开云雾的生产环境排查之旅
相关推荐
HTTP 与 TCP 的 KeepAlive 是一个东西吗?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档