长连接和心跳

介绍

  • 长连接

    首先这里所说的连接是指网络传输层的使用TCP协议经过三次握手建立的连接;长连接是指建立的连接长期保持,不管此时有无数据包的发送;有长连接自然也有短连接,短连接是指双方有数据发送时,就建立连接,发送几次请求后,就主动或者被动断开连接。

  • 心跳

    心跳这个名字比较形象,就像人体心跳一样,是用来检测一个系统是否存活或者网络链路是否通畅的一种方式,其一般做法是定时向被检测系统发送心跳包,被检测系统收到心跳包进行回复,收到回复说明对方存活。

心跳和长连接在一起介绍的原因是,心跳能够给长连接提供保活功能,能够检测长连接是否正常(这里所说的保活不能简单的理解为保证活着,具体来说应该是一旦链路死了,不可用了,能够尽快知道,然后做些其他的高可用措施,来保证系统的正常运行)。

优势

长连接的优势

  • 减少连接建立过程的耗时

    大家都知道TCP连接建立需要三次握手,三次握手也就说需要三次交互才能建立一个连接通道,同城的机器之间的大概是ms级别的延时,影响还不大,如果是北京和上海两地机房,走专线一来一回大概需要30ms,如果使用长连接,这个优化还是十分可观的。

  • 方便实现push数据

    数据交互-推模式实现的前提是网络长连接,有了长连接,连接两端很方便的互相push数据,来进行交互。

疑问

  • TCP连接到底是什么?

    所谓的TCP连接不是物理的连接,是为了实现数据的可靠传输由通信双方进行三次握手交互而建立的逻辑上的连接,通信双方都需要维护这样的连接状态信息。比如netstat经常看到连接的状态为ESTABLISHED,表示当前处于连接状态。(这里需要注意的是这个ESTABLISHED的连接状态只是操作系统认为当前还处在连接状态)

  • 是不是建立了长连接,就可以高枕无忧了呢?

    建立好长连接,两端的操作系统都维护了连接已经建立的状态,是不是这时向对端发送数据一定能到达呢?

    答案是否定的。

    可能此时链路已经不通,只是TCP层还没有感知到这一信息,操作系统层面显示的状态依然是连接状态,而且因为TCP层还认为连接是ESTABLISHED,所以作为应用层自然也就无法感知当前的链路不通。

    这种情况会导致什么问题?

    如果此时有数据想要传输,显然,数据是无法传送到对端,但是TCP协议为了保证可靠性,会重传请求,如果问题只是网线接头松了,导致网络不通,此时如果及时将网线接头接好,数据还是能正常到达对端,且TCP的连接依然是ESTABLISHED,不会有任何变化。但不是任何时候都这么巧,有时就是某段链路瘫痪了,或者主机挂了,系统异常关闭了等。这时候如果应用系统不能感知到,是件很危险的事情。

  • 长连接怎么保活?

    TCP协议实现中,是有保活机制的,也就是TCP的KeepAlive机制(此机制并不是TCP协议规范中的内容,由操作系统去实现),KeepAlive机制开启后,在一定时间内(一般时间为7200s,参数tcp_keepalive_time)在链路上没有数据传送的情况下,TCP层将发送相应的KeepAlive探针以确定连接可用性,探测失败后重试10(参数tcp_keepalive_probes)次,每次间隔时间75s(参数tcp_keepalive_intvl),所有探测失败后,才认为当前连接已经不可用。这些参数是机器级别,可以调整。

  • 应用层需要做点什么吗?

    按照TCP的KeepAlive机制,默认的参数,显然不能满足要求。那是不是调小点就可以了呢?

    调整参数,当然是有用的,但是首先参数的机器级别的,调整起来不太方便,更换机器还得记得调整参数,对系统的使用方来说,未免增加了维护成本,而且很可能忘记;其次由于KeepAlive的保活机制只在链路空闲的情况下才会起到作用,假如此时有数据发送,且物理链路已经不通,操作系统这边的链路状态还是ESTABLISHED,这时会发生什么?自然会走TCP重传机制,要知道默认的TCP超时重传,指数退避算法也是一个相当长的过程。因此,一个可靠的系统,长连接的保活肯定是要依赖应用层的心跳来保证的。

    这里应用层的心跳举个例子,比如客户端每隔3s通过长连接通道发送一个心跳请求到服务端,连续失败5次就断开连接。这样算下来最长15s就能发现连接已经不可用,一旦连接不可用,可以重连,也可以做其他的failover处理,比如请求其他服务器。

    应用层心跳还有个好处,比如某台服务器因为某些原因导致负载超高,CPU飙高,或者线程池打满等等,无法响应任何业务请求,如果使用TCP自身的机制无法发现任何问题,然而对客户端而言,这时的最好选择就是断连后重新连接其他服务器,而不是一直认为当前服务器是可用状态,向当前服务器发送一些必然会失败的请求。

设计误区

  • 无心跳

    无心跳的设计,也是很常见的,为了省事,长连接断开,TCP传输层有通知,应用程序只要处理这种通知,一旦发现连接异常,就重连。但是此类通知可能来的特别晚,比如在机器奔溃,应用程序异常退出,链路不通等情况下。

  • 被连接方检测心跳

    心跳的实现分为心跳的发送和心跳的检测,心跳由谁来发都可以,也可以双方都发送,但是检测心跳,必须由发起连接的这端进行,才安全。因为只有发起连接的一端检测心跳,知道链路有问题,这时才会去断开连接,进行重连,或者重连到另一台服务器。

    例如,client去连接server,client定时发送心跳到server,server检测心跳,发现一段时间client没有传心跳过来,认为与client的链路已经出了问题或者client自身就已经出了问题。粗看上去貌似没什么问题,但是如果只是client与当前这个server之间的链路出了问题,作为一个高可用的系统,是不是应该还有另一个server作为备选,问题出在短时间内client根本不知道自己和第一个server出了问题,所以也不会主动去连接第二个server。

  • 第三方心跳

    还有一类心跳,使用第三方保活,也就是除了客户端和服务端之外,还有另一台机器,定时发送心跳去探测服务端的存活。这类探活方法使用在检测系统的存活与否的问题上是没有问题的,但是这类设计是无法用来检测客户端和服务端之间链路的好坏。

参考方案

  • 方案一

    最简单的策略当然是客户端定时n秒发送心跳包,服务端收到心跳包后,回复客户端的心跳,如果客户端连续m秒没有收到心跳包,则主动断开连接,然后重连,将正常的业务请求暂时不发送的该台服务器上。

  • 方案二

    可能有人觉得,这样是不是传送一些无效的数据包有点多,是不是可以优化下,说实话,个人认为其实一点也不多。当然是可以做些优化的,因为心跳就是一种探测请求,业务上的正常请求除了做业务处理外,还可以用作探测的功能,比如此时有请求需要发送到服务端,这个请求就可以当作是一次心跳,服务端收到请求,处理后回复,只要服务端有回复,就表明链路还是通的,如果客户端请求比较空闲的时候,服务端一直没有数据回复,就使用心跳进行探测,这样就有效利用了正常的请求来作为心跳的功能,减少无效的数据传输。

来源链接:https://www.jianshu.com/p/c6af08f853d0

原文地址:https://www.cnblogs.com/new-journey/p/10319110.html

时间: 2024-10-11 12:06:29

长连接和心跳的相关文章

长连接和心跳包

第一种设置:通过设置socket的keepalive属性#include    "/usr/include/linux/tcp.h"#include "/usr/include/linux/socket.h"////KeepAlive实现,单位秒//下面代码要求有ACE,如果没有包含ACE,则请把用到的ACE函数改成linux相应的接口int keepAlive = 1;//设定KeepAliveint keepIdle = 5;//开始首次KeepAlive探测前

JAVA实现长连接(含心跳检测)Demo

实现原理: 长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的.       如果,长时间未发送维持连接包,服务端程序将断开连接. 客户端:       Client通过持有Socket的对象,可以随时(使用sendObject方法)发送Massage Object(消息)给服务端.       如果keepAliveDelay毫秒(程序中是2秒)内未发送任何数据,则自动发送一个KeepAlive Object(心跳)给服务端,用于维持连接.       由于,我们向服务端,可

基于netty实现的长连接,心跳机制及重连机制

技术:maven3.0.5 + netty4.1.33 + jdk1.8 概述 Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序. 也就是说,Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户.服务端应用.Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务

互联网推送服务原理:长连接+心跳机制(MQTT协议)

互联网推送消息的方式很常见,特别是移动互联网上,手机每天都能收到好多推送消息,经过研究发现,这些推送服务的原理都是维护一个长连接(要不不可能达到实时效果),但普通的socket连接对服务器的消耗太大了,所以才会出现像MQTT这种轻量级低消耗的协议来维护长连接,那么要如何维护长连接呢: 在写之前,我们首先了解一下为什么Android维护长连接需要心跳机制,首先我们知道,维护任何一个长连接都需要心跳机制,客户端发送一个心跳给 服务器,服务器给客户端一个心跳应答,这样就形成客户端服务器的一次完整的握手

移动互联网消息推送原理:长连接+心跳机制(MQTT协议)

互联网推送消息的方式很常见,特别是移动互联网上,手机每天都能收到好多推送消息,经过研究发现,这些推送服务的原理都是维护一个长连接(要不不可能达到实时效果),但普通的socket连接对服务器的消耗太大了,所以才会出现像MQTT这种轻量级低消耗的协议来维护长连接,那么要如何维护长连接呢: 在写之前,我们首先了解一下为什么Android维护长连接需要心跳机制,首先我们知道,维护任何一个长连接都需要心跳机制,客户端发送一个心跳给 服务器,服务器给客户端一个心跳应答,这样就形成客户端服务器的一次完整的握手

转 互联网推送服务原理:长连接+心跳机制(MQTT协议)

http://blog.csdn.net/zhangzeyuaaa/article/details/39028369 目录(?)[-] 无线移动网络的特点 android系统的推送和IOS的推送有什么区别 推送的实现方式 互联网推送消息的方式很常见,特别是移动互联网上,手机每天都能收到好多推送消息,经过研究发现,这些推送服务的原理都是维护一个长连接(要不不可能达到实时效果),但普通的socket连接对服务器的消耗太大了,所以才会出现像MQTT这种轻量级低消耗的协议来维护长连接,那么要如何维护长连

TCP协议的长连接,短连接以及心跳包实例

TCP连接简介 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接, 当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接, 连接的建立是需要三次握手的,而释放则需要4次握手, 所以说每个连接的建立都是需要资源消耗和时间消耗的 经典的三次握手示意图: 经典的四次握手关闭图: 一.长连接与短连接 长连接: 指在一个TCP连接上可以连续发送多个数据包, 在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接; 一般需要自己做在线

轮询、长轮询、长连接的区别

一.http长连接 https://www.cnblogs.com/gotodsp/p/6366163.html 二.轮询 客户端每隔一段时间ajax https://blog.csdn.net/woshijidutu/article/details/53894592 三.长轮询 客户端请求1--服务端hold--服务端返回--客户端请求2 长轮询与长连接是两个概念 四.tcp长连接+心跳 mqtt 原文地址:https://www.cnblogs.com/silyvin/p/9255029.h

Netty实现服务端客户端长连接通讯及心跳检测

通过netty实现服务端与客户端的长连接通讯,及心跳检测.        基本思路:netty服务端通过一个Map保存所有连接上来的客户端SocketChannel,客户端的Id作为Map的key.每次服务器端如果要向某个客户端发送消息,只需根据ClientId取出对应的SocketChannel,往里面写入message即可.心跳检测通过IdleEvent 事件,定时向服务端放送Ping消息,检测SocketChannel是否终断.         环境JDK1.8 和netty5