长连接心跳_TCP长连接及连接管理探讨

本文探讨TCP长连接的优势,如减少连接建立时间、实现pipelining和推送数据。然而,长连接带来维护成本,需要有效的连接管理和心跳检测。TCP keepalive机制用于检测不活跃连接,而应用层心跳则提供额外的检测手段。连接池通过限制最大空闲连接数和最大空闲时间来管理资源,减少端口占用。基于seq的连接池管理适用于异步RPC调用,但实现更为复杂。
摘要由CSDN通过智能技术生成
af76be706e34a1b75e1b25db449cf7f8.gif

TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP生命周期分为三个阶段:建立连接、传输数据、关闭连接。根据使用方法不同,可认为TCP连接分长连接和短连接。如果每次通信后就close掉连接,那TCP就相当于短连接。如果请求结束后保持TCP连接的状态不关闭,那TCP就是长连接。

一、为什么使用长连接

  • TCP连接的建立需要3次握手,断开需要4次挥手。使用长连接可以减少连接的建立次数,减少CPU及内存的使用

  • 实现pipelining模式

ab1e543b8b3e2a713be9408873b8e285.png

  • 实现服务端push数据给客户端

  • 减少TCP请求,减少网络堵塞

  • 减少后续请求的响应时间

  • 减少了三次握手和四次挥手的时间

单线程1000次请求数据对比:

  • TCP短连接用时:4.6s

  • TCP长连接用时:2.5s

二、长连接会有什么问题

维护成本高,随着服务的运行,建立的连接会越来越多,最终可能导致服务器不堪重负。因此如何管理连接和清理死连接(不活跃)就显得尤为重要。

(1)心跳检测

  • TCP层:KeepAlive机制

  • 应用层:心跳

TCP keepalive机制

caf9159e27ddbc662f5ac6fca3c85616.png

  • tcpkeepalivetime:在链路上没有数据传送的情况下,tcpkeepalivetime秒后触发tcp心跳

  • tcpkeepaliveintvl:心跳每个tcpkeepaliveintvl秒发送一次

  • tcpkeepaliveprobes:发送tcpkeepaliveprobes次都无响应后将断开连接

KeepAlive本质

通过抓包数据来看,是TCP发送一个数据长度为0的空包,ack最后一个包的序号,这样对应用层无影响。

默认情况下,是关闭TCP的KeepAlive机制的。

go打开KeepAlive的方法:

conn.SetKeepAlive(true)

conn.SetKeepAlivePeriod(time.Minute)

(2)连接管理

目前主要有2种连接管理方式:

  • 基于ip:port的连接池

    ip:port为key,缓存一组连接

  • 基于seq的连接池管理

    需要应用层协议支持,客户端在请求包中加入seq,收到返回包后根据seq找到相应的回调方法。

连接池

bingo服务端使用的tcp层keepalive机制检查连接状态,同时服务端支持pipeline的方式处理请求。因此在客户端可以使用连接池来复用TCP长连接,避免客户端创建大量的连接。

常见实现方式:

  • map+chan

  • map+list

使用 map + chan的方式实现

581376b873dc8123dac36e6e58183c0f.png

  • connpool:负责管理connset

  • connset:一个ip:port拥有一个connset,负责申请连接、释放连接的具体实现,使用chann缓存连接

2个参数&2个方法

a4ad9aeecf086edf9addea08410c6011.png

  • maxIdleSize:一个ip对应的最大空闲连接数。等于channel的大小

  • maxIdleTime:最大空闲时间,连接超过这个时间可认为是不活跃连接,可以直接关闭

  • Alloc:申请一个连接

  • Reclaim:把连接返回连接池,连接在使用过程中若发生error,则应该close掉连接,不应该把该连接返回连接池

申请连接时,会优先从连接池中获取链接,如果获取失败或尝试次数达到上限后才会创建新连接。

36f5ee6e6a536397816a14b49e209db7.png

数据对比

(1)不使用连接池

  • 单协程请求总数:100

  • 请求间隔时间:0~50ms

  • 协程数:500

  • 成功:51636

  • 失败:3364

  • 端口占用:50000

(2)使用连接池

  • 单协程请求总数:500

  • 请求间隔时间:0~50ms

  • 协程数:50

  • 成功:50000

  • 失败:0

  • 端口占用:5~10

优点:

    1.代码实现比较简单。

    2.上层协议无关,任何协议都可以接入连接池。

缺点:

  1. 高并发下占用过多的fd。

  2. 如果请求间隔时间为0,占用端口数=协程数。

基于seq的连接池管理

这种方式通常用于异步rpc调用

eb8732714efbf7bd64a9ce5c34a147fd.png

客户端会缓存seq->channel(存放返回包、用于回调),

客户端发包在包头中填写seq值,服务端会将seq字段原封不动的带回来,

然后通过seq查找到对应的channel,将数据放进去。等待数据的协程就可以接着处理请求了。

这种方式管理连接,通常发送请求包和接受返回包是不同的进程(写成),通过map来共享数据,完成回调等操作。

jungle中返回包处理代码:

5930c46965d86a76852ca808d0a793be.png

交互流程

a18e279053a5f8e95a9f356700154e94.png

如果conn本身是协程(进程)安全的,在alloc连接时,连接池可以不把此连接清除掉。这种情况下连接池的主要作用是根据策略做连接的负载均衡。

优点:

  1. 连接复用,理论上一个ip+port可以只对应一个连接。

  2. 基于seq复用,节省fd。

缺点:

  1. 实现复杂,异常状态多,超时、连接断开不可用等处理逻辑复杂。

  2. 需要应用层协议支持。

e5776b723703da0f8cb0e93aa374f662.png d5cace9e062a5700a20e0313e3f264ed.png TCP长连接相对短连接,传输速度快,可是实现一些高级功能,如:server可以主动发送数据给client。但是需要服务端维护连接,增加系统的复杂性。保持的连接也会占用和多系统资源,带来更多的风险。因此具体选择哪种技术,还需要根据具体情况做权衡。 d5cace9e062a5700a20e0313e3f264ed.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值