- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
先看一下wiki上的说法:
心跳包(英语:Heartbeat)在计算机科学中指一种周期性的信号,通过硬件或软件的形式来检测行为的正常与否,或者与计算机系统是否一致。[1] 通常,机器间会每隔几秒钟发送一次心跳包。 如果接收终端没有在指定时间内(通常是几个心跳包发送的时间间隔内)接收到心跳包,发送终端将会被判定发送失败.
简而言之心跳机制是用于检测对端存活的一种常用方式.
有点类似icu里面的心跳检测机(服务端),你的心脏(客户端)跳一下,他就更新一下状态,认为你还活着,你要太长时间没跳,他就认为你已经不行了,然后发出bi 的警告.
在网络中,心跳的作用是,在一种需要对端保持连接的状态中,并且存在无法通过上一次的请求判断当前的状态(虽然心跳也不能保证下一次发送成功,但是现实是,我上一次请求是12h前发的,所以你现在还在不在),心跳包可以单独检测对端的存活状态,从而防止发送无用的数据包,另外在分布式系统中,可以避免将数据发送到不可用的节点上(这是比较麻烦的,我成功地把包发到一个不可用的节点上,它给我反错误了,我怎么办,发给其它节点吗,会造成双花吗?) 。
当然心跳机制不会完美地解决上面的这些问题(毕竟我也不能保证这一秒你的心还在跳,下一秒你就一定还活着),在高可用的系统中还是需要设计另外的机制来防止双花.
另外值得说的一点是:我们不能在网络中发送过多的心跳包,因为在很多时候,网络也是一直有限的资源(心跳虽好,可不要贪杯o),当然也有设计感觉网络情况动态调整的心跳机制,不过那就涉及一些网络底层的东西了.
说到常见的心跳包,就不得不说tcp keepalive机制了 。
依然是wiki:
传输控制协议(TCP)存活包为可选特性,且默认关闭。[1]存活包内没有数据。在以太网网络中,存活包的大小为最小长度的几帧(64字节[2])。协议中[3],还有三个与存活包相关的参数:
存活时长(英语:Keepalive time)即空闲时,两次传输存活包的持续时间。TCP存活包时长可手动配置,默认不少于2个小时.
存活间隔(英语:Keepalive interval)即未收到上个存活包时,两次连续传输存活包的时间间隔.
存活重试次数(英语:Keepalive retry)即在判断远程主机不可用前的发送存活包次数。当两个主机透过TCP/IP协议相连时,TCP存活包可用于判断连接是否可用,并按需中断.
多数支持TCP协议的主机也同时支持TCP存活包。每个主机按一定周期向其他主机发送TCP包来请求回应。若发送主机未收到特定主机的回应(ACK),则将从发送主机一侧中断连接。 若其他主机在连接关闭后发送TCP存活包,关闭连接的一方将发送RST包来表明旧连接已不可用。其他主机将关闭它一侧的连接以新建连接.
空闲的TCP连接通常会每隔45秒或60秒发送一次存活包。在未连续收到三次ACK包时,连接将中断。此行为因主机而异,如默认情况下的Windows主机将在7200000ms(2小时)后发送首个存活包,随后再以1000ms的间隔发送5个存活包。若任意存活包未收到回应,连接将被中断.
keepalive作为最基础的心跳机制,其设计已经融入tcp协议中了.
wireshark keepalive捉包分析 。
TLS心跳原理rfc 6520这里就之间放rfc的原文了,感兴趣的可以去读读看.
简单来讲TLS心跳拓展主要解决的是在tls链路中,判断对方存活需要进行一次tls协商(这是比较费时),这个心跳拓展的主要目的是通过一个简单的心跳过程来保留tls链路的存活,在之前是使用tcp的keepalive来做的,但tcp的keepalive只能保证tcp链路的可用性.
看完这篇rfc,有两个比较有意思的点 。
对于每个心跳包,我们需要给他一个payload,而服务端返回的时候需要原封不动的返回这个payload。这么做我猜测是外来解决网络超时的问题,防止我受到之前的包 。
不需要时时刻刻的发送心跳包,感觉rfc的定义,我们只需要在网络空闲的时候发送心跳包,而在链路中有请求的情况下则不需要发送请求包.
心脏出血漏洞(ok,我还是懒得写,连接安排上) 。
IM系统(通讯系统)中的心跳机制主要是获取用户在线状态,以及向用户推送数据用 。
与前面两种心跳类似,不过IM系统需要面对一个麻烦的东西 -- NAT(当然TLS的心跳也有考虑NAT的因素)。对于IM系统,本质是是一个C/S架构的系统,而大部分的C都是没有独立IP的,与server通讯,全靠NAT分配的临时IP与端口,而NAT的反配权又不是C端掌控的,实际上是运营商在控制NAT的分配与释放。同时IM系统中一般C的数量会是S数量的几千-几万倍,维护心跳状态将会耗费大量的资源,不过值得庆幸的是,IM实际上是一种弱可用的系统,服务端不需要对客户端的心跳做出反应,也不需要向客户端发送心跳包,有点类似于UDP,客服端发出去就不管了。当然IM的心跳机制还是颇为复杂的,而他的复杂也不是我想要了解的信息,所以这里只给出一片作者认为还可以的博客.
上面谈到的心跳机制基本上都是网络层面的心跳机制,更多的是确认一个链路是否还可用。当然我们可以把这个链路再抽象一下,比如在一个对等网络中,你连接了某个数据库的资源,我连接了另一个数据库的资源,而我们需要保证相互之间 到数据库的链路是连通的。那么这就不是简单的tcp keepalive这种模式能解决的问题了。我们没法在网络传输模块完成整个心跳过程,网络层甚至不知道数据库是什么,所以这个请求必须上抛到应用层,而应用层在根据自身情况,去找数据库拿状态(这里有个情况,为什么不让数据库也跳起来,主要是浪费资源,心跳是检测活性,如果没有client,实际上也用不到数据库的活性,对于心跳包中复杂的请求,应该被动的等待需要的时候再去操作,而不是在主动地推送自己的状态).
当然这还会有一些问题我们包心跳的逻辑全部放在应用层,是不是对心跳是不很友好,这会导致应用层的逻辑与网络层的逻辑耦合在一起,本来应该网络层做的心跳,可所有的逻辑都在应用层,网络层就像完全没有心跳这回事.
说这么多,最后我们还是回到现实,最近我的一开发任务,为我们的分布式系统添加一个心跳检测机制.
简单描述一下我们的系统:
一个分布式的系统,每个peer会连接一个或多个资源,一个资源会被多个peer连接,当peer受到请求后会随即的把请求发送到他知道能处理这个请求的peer中。peer之间使用json_rpc通行(用rpc协议是因为我们这个过程实际上就是一个远程调用).
比如我是a,我知道b,c,d能处理 x的请求,我会随即的把请求发到b,c,d某个peer中(或者发送到第一个peer).
现在遇到的一个问题是,如果b,c,d中间有人挂机了,a是不知道的,而a还会随即的把请求发到一个节点里面.
我现在的设计方案是,在rpc模块实现心跳的逻辑,包括自动发送心跳包,判断返回结果是否正常,对于多次心跳异常的节点进行处理,(对方节点死了也要周期性的那,用于复活),也就是心跳的主要逻辑在rpc中实现(网络模块),它用于控制心跳的评论等等,然后在rpc中抽象出两个接口,HeartbeatHandler,HeartbeatClient 。
HeartbeatHandler 接口表示心跳服务端处理的接口 。
HeartbeatClient 接口表示心跳客户端的接口: 客户端接口只需要提供两个方法,一个属如果构造心跳请求的接口,一个属如何处理心跳结果的接口 。
在server 启动时,将一个HeartbeatHandler的接口注册到server中,在client实例化的时候设置HeartbeatClient 并开启心跳,而心跳的流程控制还在网络模块中.
在我的这个业务中,HeartbeatHandler接口在收到心跳请求会,回去找当前节点连接的资源获取状态,让后返回资源是否可用的结果给clinet 。
client根据结果来刷新自己的路由表,确保下次请求发送到一个状态最健康的节点上.
。
**WRAN 以上文章只是出自我的初步调研,若有疏漏,还请同好们多多指正** 。
最后此篇关于心跳包的文章就讲到这里了,如果你想了解更多关于心跳包的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在使用血氧仪开展项目。我想对其进行平滑处理,以便可以使用它来计算心跳。我正在从麦克风收集原始数据,我将它们放在新数组中,比方说,sData[]。 信号真的很疯狂,如预期的那样在整个图上跳跃,所以我
如果您错过了 - TLS Heartbeat Extension 实现中的 OpenSSL 漏洞一直在流传。欲了解更多信息,请参阅http://heartbleed.com/ . 可能的缓解步骤之一是
随着关于 heartbleed 错误的讨论不断,很难找到关于 OpenSSL 的被利用的心跳扩展究竟用于什么的信息。 此外,是否可以针对 Apache w/mod_ssl 禁用它,而无需按照建议@ h
我是 Linux 新手,正在学习 LINUX heartbeat。我正在尝试做“yum install heartbeat”,如下所示…… # cat /etc/issueRed Hat Enterp
我在我们的服务器中使用带有kibana的heartbeat,metricbeat和elasticsearch 7.5,以检查服务器状态并检查应用程序的可用性。如果应用程序或服务器已关闭或没有响应,我想
我们有一个用 Java 编写的 RMI 客户端应用程序,它需要定期向服务器应用程序发送“保持 Activity ”消息。我们将其实现为一个单独的心跳线程,它向服务器发送保持 Activity 消息,然
我不确定如何最好地让我们的服务器知道我们的 iPhone 应用程序当前正在运行(即使在后台)。有几种不同的选择,但对于 Apple 批准程序允许的以及最可靠的选项存在一些担忧。如果考虑到 Apple
我似乎找不到关于如何在 Spring 中使用 websockets 向客户端发送心跳的好资源! 我有一个使用此配置运行的基本服务器: @Configuration @EnableWebSocketMe
我正在实现一个用于分布式 cronjob 执行的系统(所谓的 cron 计算集群)。当行动时间到来时,Cronjobs 应该排队进入消息队列(RabbitMQ)。在另一侧(集群的节点/ worker
使用 python kafka api 从主题中读取只有少量消息的消息。 Kafka 不断重复播放队列中的消息。 它从我的主题接收到一条消息(返回每条消息内容),然后抛出.更多日志: kafka.co
我目前有一个异步 TCP/IP 套接字 C# WinForms 应用程序,它是“服务器”应用程序。该应用程序持有客户端的持久套接字。我想实现一个心跳包来检测半开连接。 最初我只想创建一个循环并每隔 x
socket.io documentation提到可以像这样禁用心跳: io.disable('heartbeats'); 不幸的是,虽然这似乎阻止了心跳的发送,但客户端在不发送心跳时仍会断开连接。
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
我是一名优秀的程序员,十分优秀!