心跳协议的设计与实现

来源:互联网 发布:深圳方维网络 编辑:程序博客网 时间:2024/05/01 14:04

heartbeat protocol (心跳协议)在维基百科的定义如下:

在计算机科学中,心跳是由硬件或软件产生的周期性信号,用于指示正常操作或同步计算机系统的其他部分。通常情况下,机器之间以一定的间隔以秒为单位发送心跳。 如果端点在一段时间内没有收到心跳(通常是几个心跳间隔),则应该发送心跳的机器已经失败了。

心跳协议表示连续交换消息,以确保节点将检测到任何网络中断或节点崩溃。此协议允许节点在稍后重新建立连接。它一种用于确保主节点和辅助节点间的通信网络始终处于活动状态的方法。主节点定期向辅助节点发送心跳信号。如果辅助节点未收到固定数量的心跳信号,它会检测到故障并启动心跳协议。此外,辅助节点也会发生相同的情况。

分布式系统中的心跳协议的设计
在分布式系统中一方依赖远程的另一方提供服务的系统中,需要有某种机制知道服务提供方是否还能正常提供服务。

心跳协议的基本形式是,如果进程 A 依赖于 B,那么 A 应该按固定的周期向 B 发送心跳,而 A 按固定的周期检查心跳。在这个形式中,有三个量值需要仔细考虑:心跳包的发送间隔时间 Ts,心跳包接收检查的间隔 Tc,心跳失效的超时时间 timeout。通常发一个心跳就对应接收一个,所以 Ts 应当与 Tc 相等

关于三个时间的大小设置通常要考虑一种折中方案来设计。就Ts,Tc来说,如果时间较大就不能较快知道对方情况,反应也就慢。如果时间较小,不但会增大网络负担,如果考虑到网络延迟,很有可能会发生误判的情况。

实际项目中的使用场景和实现
笔者在实际项目中有这么一个需要。对于一些实时性要求不高的任务,但却比较消耗资源的任务,为了提供用户的请求响应间隔,决定将其单独处理(在单独的进程中或是其他主机中)。对于这种解耦的操作,消息总线(Message Queue)很适合这种操作。当用户的请求被接受后,随机向MQ中丢入相应的消息,而再MQ的另一端则有单独的进程来接收并处理消息。

为了保证处理该消息进程的健壮性,需要某种机制知道该进程是否还能继续提供服务?如果进程在处理某个消息时意外被阻塞时而无法继续提供服务时是否能够实现自行重启?

考虑以上的需求,决定自己实现一个类似的心跳协议,来检测处理消息的进程。

设计思路
启动的进程中,将进程id,当前内存使用情况等消息存储在NoSQL(MongoDB或Redis)中。并对该条数据设置一个过期时间timeout(这个时间就是上述心跳的超时时间),每隔Ts个时间段该进程就对数据库中该进程的信息(内存使用情况,当前处理消息数量等等)做一次update。如果timeout时间段内没有更新则意味这该进程挂掉了,此时会有重启操作。与此同时,对于每一个进程,会有一个检测执行消息的过程的方法,如果对于某个消息检测到一定时间内还未返回,也会将该消息重新丢给队列。

代码实现

//TODO 明天再给代码吧,今晚好困

原创粉丝点击