长连接的心跳及重连设计(下)

简介: 什么场景下需要心跳呢? 目前我们接触到的大多是一些基于长连接的应用需要心跳来“保活”。 由于在长连接的场景下,客户端和服务端并不是一直处于通信状态,如果双方长期没有沟通则双方都不清楚对方目前的状态;所以需要发送一段很小的报文告诉对方“我还活着”。 同时还有另外几个目的: 服务端检测到某个客户端迟迟没有心跳过来可以主动关闭通道,让它下线。 客户端检测到某个服务端迟迟没有响应心跳也能重连获取一个新的连接。

靠谱实现


因此我们得有一个单独的线程来判断是否需要重连,不依赖于 IdleStateHandler

于是 cim 在客户端感知到网络断开时就会开启一个定时任务:



之所以不在客户端启动就开启,是为了节省一点线程消耗。网络问题虽然不可避免,但在需要的时候开启更能节省资源。



在这个任务重其实就是执行了重连,限于篇幅具体代码就不贴了,感兴趣的可以自行查阅。


同时来验证一下效果。


启动两个服务端,再启动客户端连接上一台并保持长连接。这时突然手动关闭一台服务,客户端可以自动重连到可用的那台服务节点。



启动客户端后服务端也能收到正常的 ping 消息。


利用 :info 命令查看当前客户端的链接状态发现连的是 9000端口。



:info 是一个新增命令,可以查看一些客户端信息。


这时我关掉连接上的这台节点。


kill -9 2142


这时客户端会自动重连到可用的那台节点。 这个节点也收到了上线日志以及心跳包。


服务端自动剔除离线客户端


现在来看看服务端,它要实现的效果就是延迟 N 秒没有收到客户端的 ping 包则认为客户端下线了,在 cim 的场景下就需要把他踢掉置于离线状态。


消息发送误区


这里依然有一个误区,在调用 ctx.writeAndFlush() 发送消息获取回调时。


其中是 isSuccess 并不能作为消息发送成功与否的标准。



也就是说即便是客户端直接断网,服务端这里发送消息后拿到的 success 依旧是 true


这是因为这里的 success 只是告知我们消息写入了 TCP 缓冲区成功了而已。


和我之前有着一样错误理解的不在少数,这是 Netty 官方给的回复。



相关 issue


github.com/netty/netty…


同时感谢 95老徐以及闪电侠的一起排查。


所以我们不能依据此来关闭客户端的连接,而是要像上文一样判断 Channel 上绑定的时间与当前时间只差是否超过了阈值。



以上则是 cim 服务端的实现,逻辑和开头说的一致,也和 Dubbo 的心跳机制有些类似。


于是来做个试验:正常通信的客户端和服务端,当我把客户端直接断网时,服务端会自动剔除客户端。



总结


这样就实现了文初的两个要求。


  • 服务端检测到某个客户端迟迟没有心跳过来可以主动关闭通道,让它下线。


  • 客户端检测到某个服务端迟迟没有响应心跳也能重连获取一个新的连接。


本文所有相关代码都在此处,感兴趣的可以自行查看:


github.com/crossoverJi…


相关文章
|
6月前
|
前端开发
websocket的心跳机制
websocket的心跳机制
319 3
|
Java Windows
JavaWebSocket心跳机制详解
WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议,它提供了一种简单而强大的方式来实现实时数据传输。在使用WebSocket时,心跳机制是非常关键的,它能够保持连接的稳定性并及时发现连接的异常。本文将详细解释JavaWebSocket心跳机制的实现原理和步骤。
525 0
|
3月前
|
网络协议 Java
JAVA实现心跳检测【长连接】
这篇文章介绍了Java中实现心跳检测机制的方法,包括心跳机制的简介、实现方式、客户端和服务端的代码实现,以及具体的测试结果。文中详细阐述了如何通过自定义心跳包和超时检测来维持长连接,并提供了完整的客户端和服务端示例代码。
JAVA实现心跳检测【长连接】
|
4月前
WebSocket 心跳机制如何实现
WebSocket 心跳机制如何实现
65 0
|
5月前
|
消息中间件 Serverless 网络性能优化
消息队列 MQ产品使用合集之客户端和服务器之间的保活心跳检测间隔是怎么设置的
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
6月前
MQTT协议本身是支持心跳保活机制的
MQTT协议本身是支持心跳保活机制的
662 3
|
tengine 网络协议 Linux
关于长连接服务器和客户端之间要加入心跳的一些讨论
关于长连接服务器和客户端之间要加入心跳的一些讨论
|
6月前
|
移动开发 HTML5
WebSocket心跳机制
WebSocket心跳机制
82 0
|
网络协议
选择长连接 or 短连接,大量 Timewait 的产生时如何处理?
网络通讯中,常见的两个连接类型分别是长连接和短连接。长连接指在一定时间内保持连接不断开,而短连接则指每次连接只进行一次通信,通信结束后即时断开连接。在实际应用中,不同类型的连接有着不同的应用场景和优缺点,而且在网络通讯中可能会遇到大量 Timewait 的产生,这就需要针对不同情况选择不同的处理方案。
102 1
|
监控 前端开发 网络协议
HTTP - 长连接 & 短连接 & 长轮询 & 短轮询 & 心跳机制
HTTP - 长连接 & 短连接 & 长轮询 & 短轮询 & 心跳机制
1978 0
HTTP - 长连接 & 短连接 & 长轮询 & 短轮询 & 心跳机制