08 | 智能心跳机制:解决网络的不确定性
08 | 智能心跳机制:解决网络的不确定性
讲述:袁武林
时长16:52大小11.58M
为什么需要心跳机制
降低服务端连接维护的开销
支持客户端断线重连
连接保活
心跳检测的几种实现方式
TCP Keepalive
应用层心跳
智能心跳
小结
赞 5
提建议
精选留言(27)
- 王棕生2019-09-14解答问题:如果从实现功能角度看,传输层和应用层的心跳机制没有结合的必要,因为传输层的心跳探测连接可用性,应用层的心跳机制也可以完成探测; 但从debug角度看,应用层的心跳探测机制无法定位是网络的问题还是系统的问题,此时由传输层辅助就非常好,但实现会相对复杂!
作者回复: 是的👍
共 2 条评论43 - 钢2019-09-13tcp keepalive解决网络可用性,应用层keepalive解决网络和服务可用性,应用层无法区别网络还是服务问题,加上tcp心跳包可以进一步区分,有助于客户端做动态调整24
- rfyiamcool2019-10-24能简单说下 二分法来进行心跳探测 的逻辑么?
作者回复: 其实就是下一次动态调整的心跳间隔是:当前已经确认的安全的心跳间隔最大值 和 已经确认的心跳探测过大的最小值 的中间均值。比如上一次心跳间隔是4分钟,而且连续N次都成功ack了,那么当前已经确认的安全的心跳间隔是4分钟,假设已经确认10分钟时心跳间隔过大了,那么下一次调整的心跳就是 4 + 10 / 2 = 7分钟。
共 2 条评论10 - 隰有荷2019-09-20看了老师的讲解,在理论上是明白了,但是具体实践上该如何操作?比如:tcp的keepalive该如何通过具体的代码语言去实现。这些具体操作性的知识,不知道本课程后面是否有涉及到?
作者回复: tcp的keepalive开启比较简单,比如netty下可以通过如下代码开启: ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); 另外tcp keepalive的心跳间隔的配置也需要修改一下系统的/etc/sysctl.conf,类似下面: net.ipv4.tcp_keepalive_time=120 net.ipv4.tcp_keepalive_intvl=30 net.ipv4.tcp_keepalive_probes=3
9 - newzai2019-09-13智能心跳,采用什么算法逼近或者选择心跳周期?如何感知当前的心跳周期是否太小?因为一旦太大就会导致连接断开
作者回复: 比较常见的有二分法。
5 - dongdong2019-09-16请问老师,我这里使用应用层发心跳包,很奇怪在内网测试环境,网页一直不操作都不会断线,但在外网同套代码,不操作1,2个小时后,网页的长链接就会断线,WS脚本重连也连不上,但只要重新刷新页面就可以连上了,这是什么原因?
作者回复: 心跳间隔是多少?外网的中间路由环节和运营商网络都可能在 一个连接一段时间没有数据传输的时候 从NAT表删除这个连接的映射。所以心跳间隔最好不要大于5分钟。
3 - 云师兄2019-09-13服务端在进行推送时候,假设判断用户连接有效,即用户在线,此时推送是同时推与客户端应用保持的长连接和apns等多条通道吗?然后在客户端去重?还是每次只会选择一条通道?
作者回复: 会双推,走APNs不会直接落地app的db,苹果会根据应用在前台还是在后台来决定要不要展示APNs走通知栏的消息。现在也有很多应用支持应用在前台时也展示通知栏的消息,看具体需求。
3 - Geek_e7834d2019-10-17看流程图,服务器检查心跳并不是定时的, 而只是推送的时候检测?
作者回复: 具体是哪个图呀,理解不太对,心跳和推送是独立的,并不会在推送的时候进行检测,一般会由独立的定时器来根据一定时间内socket中是否有数据收发来定时触发的。
2 - 花指令2019-09-16老师好,我用go的tcpsocket,有一端异常退出时,另一端会触发掉线通知。所以我不明白的是,socket是不是不需要心跳?还是是因为我是在局域网测试,和公网情况不一样?
作者回复: 因为tcp本身是一个虚拟连接,中间链路断开的话另一端是感知不到的,另外,移动运营商的NAT会对一段时间没有数据传输的连接切断,所以对于维护高可用的一条长连接心跳是必不可少的。
共 4 条评论2 - 大魔王汪汪2019-09-14老师 客户端或服务端心跳实现是在客户端维持一个轮训服务吗?这样会不会有浪费客户端资源的问题,有没有什么好方法解决轮训定时器这种资源浪费问题
作者回复: 一种方式是客户端采用固定timer来定时发送心跳包,也可以在客户端没有消息收发后的一段时间才可以发送心跳包,这样能节约一些流量。
2 - 一步2019-09-14我看上图 心跳处理流程,只有客户端当判断连接无效的时候才会进行 连接重连,重连的这个动作服务端不会进行吗? 如果这样的话服务端还要发送心跳消息进行心跳检测做什么呢?服务端是不是可以这样处理,当一段时间没有收到客户端的心跳包的时候就判断与该客户端的心跳连接断开了,直接释放对应的资源不就可以了吗?
作者回复: 服务端不知道客户端的固定连接地址呀,所以重连一般都是由客户端发起。服务端一般不需要发送心跳,是由客户端来发送心跳,服务端一段时间没有收到客户端的心跳包的时候就可以判断连接异常,主动断开等客户端重连上线就可以了。
3 - 0xTang2020-03-28心跳一般只需端到服,这样端检测超时可以发起重连。1
- Geek_a2849d2020-03-05老师您好,希望您能帮我解答下,公司开发的移动端IM,服务端设置心跳超时时间120秒,客户端30秒发送心跳包,但是安卓端还是会频繁掉线,有的时候停留在app聊天页面也会断线,请问下这个是什么原因呢?
作者回复: 这个最好双端抓包来分析一下,看下最终的断线是哪一边主动发起的,比如安卓息屏或者切后台之类的是否有断连的操作。
1 - wuhaka2019-10-31老师您好,您这节只讲了tcp的心跳机制,我觉得可以采用类似QUIC协议,自定义connection id判断逻辑连接状态,无需通过通信五元组来判断是否为同一连接,这样可以避免各种NAT设备,或nginx代理等出现的映射失效问题,在复杂网络环境中不用在频繁断线重连节省开销
作者回复: 是个好想法,不过QUIC之所以能够实现抽象的connection id应该也是得益于底层依赖的UDP是无状态传输协议,基于TCP之上要解决连接迁移的问题估计会很难。要是你有一些思路咱们可以继续探讨一下。
1 - Csquare2019-10-24如果用了长连接,怎么支持显示用户在线状态的功能了,保活机制会让用户一直在线吧?
作者回复: 在线状态可以在用户完成上线操作后记录到uid维度的存储里供使用。保活机制不一定能保证用户一直在线,只是能降低运营商NAT超时导致连接被强制中断的概率,同时通过心跳保活还能及时发现连接是否可用,从而快速进行重连,来提升连接的可用性。
1 - Geek_e986e32019-09-15智能心跳的算法是咋样的
作者回复: 一般可以采用二分法来进行心跳探测。
1 - pdf2022-02-15老师,各位同学 如果服务端检测心跳超时之前,链接处于假死状态,服务端认为该链接可用,发送push消息,此时写tcp buffer是会成功还是失败呢?
- 极客—月2021-07-16老师,有个疑问望解答下,大量用户在心跳检测下线后,服务端应该采用怎样的方式清理用户好呢?(我们使用LRU清理,但是Go中List是非线程安全的,所以只能单线程清理,大量用户下线时,往往清理不过来)
- 倔强小德普2020-05-20客户端是发送心跳包检测 长链状态的。服务端一般通过什么机制,来识别长链是否健康。根据最后一次消息的时间吗
- lin yu2020-04-17看着是很明白了,但是写不出来,应用层心跳怎么通过具体代码实现共 1 条评论