两种心跳机制

TCP长连接中可能出现的问题:

1 很多防火墙路由器等对于空闲socket自动关闭
2 对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制.

为了解决这些问题,就有了心跳(HeartBeat)机制。

两种实现机制:

目前而言,有两种方式实现TCP的保活(业内现状是IM方面几乎都采用第一种)。

TCP选项Keepalive

打开TCP协议已有的SO_KEEPALIVE选项. 一般实现在服务器侧,客户端被动响应前面一篇博客有具体介绍,这里就不多讲了。

应用层协HeartBeat

很多应用层协议都有HeartBeat机制,由应用自己实现的应用层的心跳, 为心跳消息额外定义一个消息类型。通常是客户端每隔一小段时间向服务器发送一个数据包,通知服务器自己仍然在线,并传输一些可能必要的数据。使用心跳包的典型协议是IM,比如QQ/MSN/飞信等协议。

两种机制的优缺点:

TCP选项Keepalive

优点:

1 系统内核完全替上层应用自动给做好了,内核层面计时器相比上层应用,更为高效
2 上层应用只需要处理数据收发、连接异常通知即可。
3 使用起来简单, 减少了应用层代码的复杂度. 也会更节省流量, 因为应用层的数据传输到TCP协议层时都会被加上额外的包头包尾. 由TCP协议提供的检活, 其发的探测包, 理论上实现的会更精妙, 耗费更少的流量.。

缺点:

1 keepAlive只能检测连接存活,而不能检测连接可用,比如某台服务器因为某些原因导致负载超高,CPU满了,无法响应任何业务请求,但是使用 TCP 探针则仍旧能够确定连接状态,这就是典型的连接活着但业务提供方已死的状态,对客户端而言,这时的最好选择就是断线后重新连接其他服务器,而不是一直认为当前服务器是可用状态,一直向当前服务器发送些必然会失败的请求;

2 如果tcp连接的另一端突然掉线,这个时候我们并不知道网络已经关闭。而此时,如果有发送数据失败,tcp会自动进行重传。重传包的优先级高于keepalive的包,那就意味着,我们的keepalive总是不能发送出去。 而此时,我们也并不知道该连接已经出错而中断。在较长时间的重传失败之后,我们才会知道。

应用层HeartBeat

优点:
1 有着更大的灵活性,可以控制检测时机,间隔和处理流程,甚至可以在心跳包上附带额外信息,最重要的是可以做到没有上面所说的缺点,不光可以检测连接存在,还可以检测连接可用。

2 通用, 应用层的心跳不依赖协议. 如果有一天不用TCP要改为UDP了, 协议层不提供心跳机制了, 但是你应用层的心跳依旧是通用的, 可能只需要做少许改动就可以继续使用。

缺点:
需要自己实现,增加开发工作量,由于应用特定的网络框架,还可能增加代码结构的复杂度,应用层心跳的流量消耗还是更大的,毕竟这本质上还是个普通的数据包。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Python心跳机制是一种用于保持连接活跃的机制,它可以确保两个通信实体之间的连接持续存在,并及时检测到连接中断的情况。双向心跳是指在通信的两个实体之间同时进行心跳检测。 在Python中,可以使用socket模块来实现心跳机制。具体步骤如下: 1. 服务器端和客户端分别创建一个socket对象,并建立连接。 2. 服务器端和客户端分别设置一个定时器,定时发送心跳消息给对方。 3. 服务器端和客户端分别设置一个定时器,定时检测是否收到对方的心跳消息。 4. 如果服务器端或客户端在规定时间内没有收到对方的心跳消息,则认为连接已断开,可以进行相应的处理。 以下是一个简单的示例代码,演示了Python中实现双向心跳机制的过程: 服务器端代码: ```python import socket import time def heartbeat_server(): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 8888)) server_socket.listen(1) conn, addr = server_socket.accept() print('Connected by', addr) while True: try: # 发送心跳消息 conn.sendall(b'heartbeat') # 等待接收心跳消息 data = conn.recv(1024) if not data: print('Connection closed') break print('Received', data) time.sleep(1) # 模拟处理其他业务 except ConnectionResetError: print('Connection reset') break conn.close() server_socket.close() heartbeat_server() ``` 客户端代码: ```python import socket import time def heartbeat_client(): client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('localhost', 8888)) while True: try: # 等待接收心跳消息 data = client_socket.recv(1024) if not data: print('Connection closed') break print('Received', data) # 发送心跳消息 client_socket.sendall(b'heartbeat') time.sleep(1) # 模拟处理其他业务 except ConnectionResetError: print('Connection reset') break client_socket.close() heartbeat_client() ``` 以上代码实现了一个简单的双向心跳机制,服务器端和客户端通过发送和接收心跳消息来保持连接的活跃状态。你可以根据实际需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值