目录
在虚拟机上安装并启动RabbitMQ服务端,使用C++客户端程序按设置速度生产消息,实测RabbitMQ流控场景。
网上搜索了相关信息,了解到RabbitMQ有三种流量控制:
是面向每一个连接做的流量控制。即,RabbitMQ 会主动阻塞(Block)那些发布消息太快的连接(Connections),无需做任何配置。如果连接被阻塞了,那么它在 rabbitmqctl 控制台上会显示一个blocked的状态。RabbitMQ 的流量控制机制是基于信用证(Credit)的拥塞控制机制。
RabbitMQ 会在启动时检测机器的物理内存数值。默认当 MQ 占用 40% 以上内存时,MQ 会主动抛出一个内存警告并阻塞所有连接(Connections)。可以通过修改 rabbitmq.config 文件来调整内存阈值,默认值是 0.4,如下所示:
[{rabbit, [{vm_memory_high_watermark, 0.4}]}].
默认情况,如果剩余磁盘空间在 1GB 以下,RabbitMQ 主动阻塞所有的生产者。这个阈值也是可调的。
本人使用的是虚拟机(1核,1G内存),相关配置如下:
[root@localhost ~]# top
top - 20:46:59 up 3 days, 23:52, 3 users, load average: 0.00, 0.06, 0.05
Tasks: 129 total, 1 running, 128 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.5%us, 1.7%sy, 0.0%ni, 97.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1004412k total, 821264k used, 183148k free, 254304k buffers
Swap: 2031608k total, 0k used, 2031608k free, 186024k cached
[root@localhost ~]# cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 94
model name : Intel(R) Core(TM) i3-6100 CPU @ 3.70GHz
stepping : 3
cpu MHz : 3696.269
cache size : 3072 KB
fpu : yes
fpu_exception : yes
cpuid level : 22
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc up arch_perfmon xtopology tsc_reliable nonstop_tsc unfair_spinlock pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch arat xsaveopt fsgsbase bmi1 avx2 smep bmi2 invpcid
bogomips : 7392.53
clflush size : 64
cache_alignment : 64
address sizes : 43 bits physical, 48 bits virtual
power management:
[root@localhost ~]#
主要是关于erlang-17.4-1.el6.x86_64.rpm和rabbitmq-server-3.6.1-1.noarch.rpm的安装,以及rabbitmq的virtual host、Exchanges、Queues的配置。
见
启动之后,可以根据web页面的Overview看到,内存使用情况与内存告警阈值,以及磁盘空间使用情况和磁盘空间告警阈值。如下图:
OK,针对RabbitMQ的三种流控机制,分别进行实测。看看表现。
由于RabbitMQ的web页面最小刷新时间是5秒(见上图右下角),所以为了能连续观察20个周期(即需要连续发送100秒),并且为了保持较稳定的生产速度,我们设置rabbitmq-client每秒生产100条消息(简单点就是生产1条消息休眠10毫秒,实际上这样生产速度达不到100,不过没关系)。即连续发送100秒,每秒生产100条消息,最终生产1W条消息。
代码中设置如下:
unsigned int tps = 100;
unsigned int period = 20;
rabbitmq-server启动之后,内存占用为48M,告警阈值为392M。
为了快速达到告警测试效果,需要修改内存high watermark,设置为55M,如下:
rabbitmqctl set_vm_memory_high_watermark absolute 55MB
注意:实际上rabbitmq-server的日志显示只设置了52M。
rabbitmq-server日志显示设置了52M
web页面也显示只设置了52M。
OK,下面这张图是测试结束截图(预期生产1W条消息,实际只生产了3505条消息便被阻塞)。
在测试过程冲,发现rabbitmq-server打印了相关的日志,分析一下日志。
=INFO REPORT==== 5-Jun-2018::22:47:36 ===
accepting AMQP connection <0.2926.0> (192.168.45.132:38126 -> 192.168.45.131:5672)
接收到1个AMQP连接
=INFO REPORT==== 5-Jun-2018::22:47:43 ===
vm_memory_high_watermark set. Memory used:55535400 allowed:55000000
使用内存了55535400B,超过了允许使用的55000000B
=WARNING REPORT==== 5-Jun-2018::22:47:43 ===
memory resource limit alarm set on node rabbit@localhost.
触发告警了,设置rabbit@localhost节点内存资源限制告警
**********************************************************
*** Publishers will be blocked until this alarm clears ***
**********************************************************
OK,大字报告警,生产者将被阻塞直到这个告警解除
=INFO REPORT==== 5-Jun-2018::22:47:44 ===
vm_memory_high_watermark clear. Memory used:53626816 allowed:55000000
OK,1秒之后,告警解除了,使用内存了53626816B,还不到允许使用的55000000B
=WARNING REPORT==== 5-Jun-2018::22:47:44 ===
memory resource limit alarm cleared on node rabbit@localhost
rabbit@localhost节点内存资源限制告警解除
=WARNING REPORT==== 5-Jun-2018::22:47:44 ===
memory resource limit alarm cleared across the cluster
=INFO REPORT==== 5-Jun-2018::22:47:51 ===
vm_memory_high_watermark set. Memory used:55116664 allowed:55000000
=WARNING REPORT==== 5-Jun-2018::22:47:51 ===
memory resource limit alarm set on node rabbit@localhost.
OK,又触发告警了。为什么呢?
**********************************************************
*** Publishers will be blocked until this alarm clears ***
**********************************************************
=INFO REPORT==== 5-Jun-2018::22:47:52 ===
vm_memory_high_watermark clear. Memory used:54410872 allowed:55000000
告警再次被清除
=WARNING REPORT==== 5-Jun-2018::22:47:52 ===
memory resource limit alarm cleared on node rabbit@localhost
=WARNING REPORT==== 5-Jun-2018::22:47:52 ===
memory resource limit alarm cleared across the cluster
=INFO REPORT==== 5-Jun-2018::22:47:53 ===
vm_memory_high_watermark set. Memory used:55155536 allowed:55000000
=WARNING REPORT==== 5-Jun-2018::22:47:53 ===
memory resource limit alarm set on node rabbit@localhost.
**********************************************************
*** Publishers will be blocked until this alarm clears ***
**********************************************************
=INFO REPORT==== 5-Jun-2018::22:47:55 ===
vm_memory_high_watermark clear. Memory used:53511456 allowed:55000000
=WARNING REPORT==== 5-Jun-2018::22:47:55 ===
memory resource limit alarm cleared on node rabbit@localhost
=WARNING REPORT==== 5-Jun-2018::22:47:55 ===
memory resource limit alarm cleared across the cluster
=INFO REPORT==== 5-Jun-2018::22:47:56 ===
vm_memory_high_watermark set. Memory used:55911656 allowed:55000000
=WARNING REPORT==== 5-Jun-2018::22:47:56 ===
memory resource limit alarm set on node rabbit@localhost.
**********************************************************
*** Publishers will be blocked until this alarm clears ***
**********************************************************
=INFO REPORT==== 5-Jun-2018::22:47:58 ===
vm_memory_high_watermark clear. Memory used:53854680 allowed:55000000
=WARNING REPORT==== 5-Jun-2018::22:47:58 ===
memory resource limit alarm cleared on node rabbit@localhost
=WARNING REPORT==== 5-Jun-2018::22:47:58 ===
memory resource limit alarm cleared across the cluster
=INFO REPORT==== 5-Jun-2018::22:47:59 ===
vm_memory_high_watermark set. Memory used:56165728 allowed:55000000
=WARNING REPORT==== 5-Jun-2018::22:47:59 ===
memory resource limit alarm set on node rabbit@localhost.
**********************************************************
*** Publishers will be blocked until this alarm clears ***
**********************************************************
=INFO REPORT==== 5-Jun-2018::22:48:03 ===
vm_memory_high_watermark clear. Memory used:54345856 allowed:55000000
=WARNING REPORT==== 5-Jun-2018::22:48:03 ===
memory resource limit alarm cleared on node rabbit@localhost
=WARNING REPORT==== 5-Jun-2018::22:48:03 ===
memory resource limit alarm cleared across the cluster
=INFO REPORT==== 5-Jun-2018::22:48:04 ===
vm_memory_high_watermark set. Memory used:58138112 allowed:55000000
=WARNING REPORT==== 5-Jun-2018::22:48:04 ===
memory resource limit alarm set on node rabbit@localhost.
**********************************************************
*** Publishers will be blocked until this alarm clears ***
**********************************************************
实际上,在测试过程中观察发现,每次告警之后,rabbitmq-client都可以继续发送(由于rabbitmq-client没有打印时间,不确定发送的速度是否受影响)。为什么呢?
第1次告警
:在22:47:43触发,此时内存使用了55535400
,超过了55000000,所以告警了。
22:47:44时,仅1秒之后,内存使用降到53626816
,没有超过55000000,所以告警解除了。
说明内存告警触发了某些机制,导致内存使用降低,解除了告警。
第2次告警
:在22:47:51触发,此时内存使用了55116664
,超过了55000000,所以告警了。
22:47:52时,仅1秒之后,内存使用降到54410872
,没有超过55000000,所以告警解除了。
第3次告警
:在22:47:53触发,此时内存使用了55155536
,超过了55000000,所以告警了。
22:47:55时,2秒之后,内存使用降到53511456
,没有超过55000000,所以告警解除了。
第4次告警
:在22:47:56触发,此时内存使用了55911656
,超过了55000000,所以告警了。
22:47:58时,2秒之后,内存使用降到53854680
,没有超过55000000,所以告警解除了。
第5次告警
:在22:47:59触发,此时内存使用了56165728
,超过了55000000,所以告警了。
22:48:03时,4秒之后,内存使用降到54345856
,没有超过55000000,所以告警解除了。
第6次告警
:在22:48:04触发,此时内存使用了58138112
,超过了55000000,所以告警了。
然后rabbitmq-client被阻塞,一直未恢复。
rabbitmq-client实际显示实际生产了3505条消息,web页面显示一共有2,579条消息。
rabbitmq-client