文档章节

rabbitmq——heartbeat

hncscwc
 hncscwc
发布于 2014/01/23 16:29
字数 944
阅读 6844
收藏 79

heartbeat通常用来检测通信的对端是否存活(未正常关闭socket连接而异常crash)。其基本原理是检测对应的socket连接上数据的收发是否正常,如果一段时间内没有收发数据,则向对端发送一个心跳检测包,如果一段时间内没有回应则认为心跳超时,即认为对端可能异常crash了。

rabbitmq也不例外,heatbeat在客户端和服务端之间用于检测对端是否正常,即客户端与服务端之间的tcp链接是否正常。

1. heartbeat检测时间间隔的设置

1). 服务端的设置

heartbeat检测时间间隔可在配置文件rabbitmq.config中增加配置项{heartbeat,Timeout}进行配置,其中Timeout指定时间间隔,单位为秒。

例如:

如果没有进行配置,默认的时间间隔为600秒(最新版本3.2.2修改为580秒)

在rabbit.app中有heartbeat的配置项。

2). 客户端的设置

根据AMQP协议,rabbitmq会通过connection.tune信令将heartbeat检测时间间隔告知客户端,客户端可以根据需要重新设置该值,并通过Connection.tune-ok信令将时间间隔再告诉给rabbitmq,rabbitmq会以客户端的时间作为该tcp连接上heartbeat检测的间隔时间。

这里要注意的是:如果时间间隔配置为0,则表示不启用heartbeat检测。

如果启用了rabbitmq_management的话,从web控制台可以看到客户端的检测的时间间隔。

2. heartbeat的实现

rabbitmq在收到来自客户端的connection.tune-ok信令后,启用心跳检测,rabbitmq会为每个tcp连接创建两个进程用于心跳检测,一个进程定时检测tcp连接上是否有数据发送(这里的发送是指rabbitmq发送数据给客户端),如果一段时间内没有数据发送给客户端,则发送一个心跳包给客户端,然后循环进行下一次检测;另一个进程定时检测tcp连接上是否有数据的接收,如果一段时间内没有收到任何数据,则判定为心跳超时,最终会关闭tcp连接。另外,rabbitmq的流量控制机制可能会暂停heartbeat检测,这里不展开描述。

涉及的源码:

start(SupPid, Sock, SendTimeoutSec,
      SendFun, ReceiveTimeoutSec, ReceiveFun) ->
    %%数据发送检测进程
    {ok, Sender} = start_heartbeater(SendTimeoutSec, SupPid, Sock,
                                     SendFun, heartbeat_sender,
                                     start_heartbeat_sender),
    %%数据接收检测进程
    {ok, Receiver} = start_heartbeater(ReceiveTimeoutSec, SupPid,
                                       Sock, ReceiveFun,
                                       heartbeat_receiver,
                                       start_heartbeat_receiver),
    {Sender, Receiver}.

start_heartbeat_sender(Sock, TimeoutSec, SendFun) ->
    %% the 'div 2' is there so that we don't end up waiting for
    %% nearly 2 * TimeoutSec before sending a heartbeat in the
    %% boundary case
    heartbeater({Sock, TimeoutSec * 1000 div 2, send_oct, 0,
                 fun () -> SendFun(), continue end}).

start_heartbeat_receiver(Sock, TimeoutSec, ReceiveFun) ->
    %% we check for incoming data every interval, and time out after
    %% two checks with no change. As a result we will time out
    %% between 2 and 3 intervals after the last data has been
    %% received
    heartbeater({Sock, TimeoutSec * 1000, recv_oct, 1,
                fun () -> ReceiveFun(), stop end}).

heartbeater({Sock, TimeoutMillisec, 
             StatName, Threshold, Handler} = Params,
            Deb,
            {StatVal, SameCount} = State) ->
    Recurse = fun (State1) -> heartbeater(Params, Deb, State1) end,
    receive
        ...
    %% 定时检测
    after TimeoutMillisec ->
        case rabbit_net:getstat(Sock, [StatName]) of
            {ok, [{StatName, NewStatVal}]} ->
                %% 收发数据有变化
                if NewStatVal =/= StatVal ->
                       %%重新开始检测
                       Recurse({NewStatVal, 0});
                   %%未达到指定次数, 发送为0, 接收为1
                   SameCount < Threshold ->
                       %%计数加1, 再次检测
                       Recurse({NewStatVal, SameCount + 1});
                   %%heartbeat超时
                   true ->
                       %%对于发送检测超时, 向客户端发送heartbeat包
                       %%对于接收检测超时, 向父进程发送超时通知
                       %%由父进程触发tcp关闭等操作
                       case Handler() of
                           %%接收检测超时
                           stop     -> ok;
                           %%发送检测超时
                           continue -> Recurse({NewStatVal, 0})
                       end;
           ...

 

 

收发检测的时候利用了inet模块的getstat,查看socket的统计信息

 

recv_oct: 查看socket上接收的字节数

send_oct: 查看socket上发送的字节数

inet详细见这里: http://www.erlang.org/doc/man/inet.html

© 著作权归作者所有

共有 人打赏支持
hncscwc
粉丝 67
博文 70
码字总数 76137
作品 0
杭州
程序员
私信 提问
加载中

评论(9)

寒沙胜雪
寒沙胜雪

引用来自“狼来了而已”的评论

刚刚解决TCP长连接的问题
求解决方案,有时候会超时。
leeyi
leeyi

引用来自“狼来了而已”的评论

刚刚解决TCP长连接的问题

什么是长链接问题?怎么解决的,能够描述下吗
hncscwc
hncscwc

引用来自“ajianrelease”的评论

我启用了management啊,为何timeout列还是空的呢?注:os是windows7
我在win7下试过了都是OK的 你确定客户端连接后,timeout列显示为空?
ajianrelease
ajianrelease
我启用了management啊,为何timeout列还是空的呢?注:os是windows7
leeOwnWell
leeOwnWell

dfg
狼来了而已
狼来了而已
刚刚解决TCP长连接的问题
hysjw
hysjw
收藏了 多谢
那句诺言
那句诺言
年后应该会用到,收藏了
摩云飞
摩云飞
清晰明了~~
RabbitMQ 3.7.9 发布,Erlang 的 AMQP 开源实现

RabbitMQ 3.7.9 已发布,这是一个维护版本,主要聚焦于修复 bug 和可用性改进。 兼容性说明 此版本与早期的 3.7.x 没有已知的不兼容性。 升级至 Erlang 21.0 升级该版本会同时将 Erlang 更新...

淡漠悠然
11/16
975
1
RabbitMQ 安装 —— Windows 7

RabbitMQ 安装 —— Windows 7 本文是在 Windows 7(64 bit)操作系统中安装 RabbitMQ 的指导。 下载并安装 Erlang,本文使用 ; 设置 Windows 环境变量 ,指向 Erlang 安装根目录,注意:如...

HiJ
11/29
0
0
RabbitMQ死循环-延长ACK时间

一、应用背景   今天做一个需求,要将RabbitMQ中的任务取出并执行,为防止任务执行期间出错,设置NO_ACK=FALSE标志,这样、一旦任务没有应答的话,相应的任务就会被RabbitMQ自动Re-Queue,...

ITACHl
08/08
0
0
RabbitMQ安装(CentOS 7 64位)

一、安装Erlang 详细的安装介绍在这里(https://www.erlang-solutions.com/downloads/download-erlang-otp) wget http://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rp......

nibilly
2015/04/28
0
0
RabbitMQ系列(一)RabbitMQ在Ubuntu上的环境搭建

环境配置 Ubuntu Server 18.04 RabbitMQ 3.6.10 安装之前 我们使用apt-get进行RabbitMQ安装,在安装之前,强烈建议您把apt源换位国内,大大增加下载安装的速度,点击查看:《Ubuntu apt-get和...

王磊的博客
06/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

docker快速搭建几个常用的第三方服务

本次和大家分享的内容是使用docker快速搭建工作中常用的第三方的服务,对于有一些互联网背景的公司来说,以下几个服务都是很需要的:redis,rabbit,elasticsearch; 如果想学习Java工程化、...

编程SHA
25分钟前
3
0
我的Linux系统九阴真经

在今天,互联网的迅猛发展,科技技术也日新月异,各种编程技术也如雨后春笋一样,冒出尖来了。各种创业公司也百花齐放百家争鸣,特别是针对服务行业,新型互联网服务行业,共享经济等概念的公...

linuxprobe16
34分钟前
10
0
Dubbo标签解析详解

在Spring继承dubbo时,会使用dubbo自定义的标签来定义相关的属性,常见的标签有<dubbo:application/>,<dubbo:registry/>,<dubbo:service/>等。对于这些标签的解析,dubbo都是使用的统一的方...

爱宝贝丶
39分钟前
5
0
网站彩蛋

图形类彩蛋 知乎 https://www.zhihu.com/ 想来知乎工作?请发送邮件到 jobs@zhihu.com 天猫 https://www.tmall.com/ 喵~ 加入我们吧 http://tb.cn/iS8NBOy 超级课程表 http://www.super.cn/...

临江仙卜算子
46分钟前
9
0
ThreadLocal父子线程之间的数据传递问题

一、问题的提出 在系统开发过程中常使用ThreadLocal进行传递日志的RequestId,由此来获取整条请求链路。然而当线程中开启了其他的线程,此时ThreadLocal里面的数据将会出现无法获取/读取错乱...

nonnetta
55分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部