短连接:每次通信时,创建 Socket;一次通信结束,调用 socket.close()。这就是一般意义上的短连接,短连接的好处是管理起来比较简单,存在的连接都是可用的连接,不需要额外的控制手段。
长连接:每次通信完毕后,不会关闭连接,这样就可以做到连接的复用。长连接的好处便是省去了创建连接的耗时。
连接的保活:KeepAlive
首先想到的是 TCP 中的 KeepAlive 机制。KeepAlive 并不是 TCP 协议的一部分,但是大多数操作系统都实现了这个机制。KeepAlive 机制开启后,在一定时间内(一般时间为 7200s,参数tcp_keepalive_time)在链路上没有数据传送的情况下,TCP 层将发送相应的KeepAlive探针以确定连接可用性,探测失败后重试 10(参数tcp_keepalive_probes)次,每次间隔时间 75s(参数tcp_keepalive_intvl),所有探测失败后,才认为当前连接已经不可用。
KeepAlive 机制是在网络层面保证了连接的可用性,但站在应用框架层面我们认为这还不够。主要体现在两个方面:
KeepAlive 的开关是在应用层开启的,但是具体参数(如重试测试,重试间隔时间)的设置却是操作系统级别的,位于操作系统的/etc/sysctl.conf配置中,这对于应用来说不够灵活。
KeepAlive 的保活机制只在链路空闲的情况下才会起到作用,假如此时有数据发送,且物理链路已经不通,操作系统这边的链路状态还是 ESTABLISHED,这时会发生什么?自然会走 TCP 重传机制,要知道默认的 TCP 超时重传,指数退避算法也是一个相当长的过程。
KeepAlive 本身是面向网络的,并不是面向于应用的,当连接不可用时,可能是由于应用本身 GC 问题,系统 load 高等情况,但网络仍然是通的,此时,应用已经失去了活性,所以连接自然应该认为是不可用的。
看来,应用层面的连接保活还是必须要做的。
连接的保活:应用层心跳
如何理解应用层的心跳?简单来说,就是客户端会开启一个定时任务,定时对已经建立连接的对端应用发送请求(这里的请求是特殊的心跳请求),服务端则需要特殊处理该请求,返回响应。如果心跳持续多次没有收到响应,客户端会认为连接不可用,主动断开连接。不同的服务治理框架对心跳,建连,断连,拉黑的机制有不同的策略,但大多数的服务治理框架都会在应用层做心跳,Dubbo 也不例外。
TCP和 HTTP 的 KeepAlive 区别对待
HTTP 协议的 KeepAlive 意图在于连接复用,同一个连接上串行方式传递请求-响应数据
TCP 的 KeepAlive 机制意图在于保活、心跳,检测连接错误。
这压根是两个概念。
网友评论