文档章节

消息队列RabbitMQ和ActiveMQ的生产者流量控制

旁观者-郑昀
 旁观者-郑昀
发布于 2012/10/11 00:18
字数 1464
阅读 1656
收藏 45

20120825 郑昀

Q:MQ 们为什么要做生产者流量控制?
A:麻烦就在于:『像 Erlang 的虚拟机实现和设计上都没有阻止用户往一个进程的消息队列里扔消息,当消息的生产速度过快,超过进程的处理能力时,这些消息就堆积起来,占用越来愈多的内存,最终导致VM崩溃。』 
Q:我为什么要知道 MQ 在做生产者流量控制?
A:当你发现自家的 Producers 动辄被挂起或被阻塞时,你要知道该调 Consumer 的消费速率,还是调 Memory Threshold of MQ 。

一,RabbitMQ 2.8.0+的流量控制
http://www.rabbitmq.com/img/rabbitmq_logo_strap.png
RabbitMQ 2.8.0+引入了一个新特性“internal flow control”。
至此 RabbitMQ 有三种流量控制:
 
1.1. Per-Connection Flow Control
是面向每一个连接做的流量控制。
即,RabbitMQ 会主动阻塞(Block)那些发布消息太快的连接(Connections),无需做任何配置。
如果连接被阻塞了,那么它在 rabbitmqctl 控制台上会显示一个blocked的状态。
RabbitMQ 的流量控制机制是基于信用证(Credit)的拥塞控制机制,后面 郑昀会在附录A中列出这个古老控制机制的详细介绍。
 
1.2. Memory-Based Flow Control
RabbitMQ 会在启动时检测机器的物理内存数值。默认当 MQ 占用 40% 以上内存时,MQ 会主动抛出一个内存警告并阻塞所有连接(Connections)。
你也可以通过修改  rabbitmq.config 文件来调整内存阈值,默认值是 0.4,如下所示:
[{rabbit, [{vm_memory_high_watermark, 0.4}]}].

当 MQ 启动时,该内存阈值也会写入到  RABBITMQ_NODENAME.log 文件里,如下所示:

Memory limit set to 2048MB.
如果 MQ Server 不能识别你的系统,或者你在用 Windows 系统,那么它会写一个警告信息到  RABBITMQ_NODENAME .log 文件里,如下所示:
=WARNING REPORT==== 29-Oct-2009::17:23:44 ===
Unknown total memory size for your OS {unix,magic_homebrew_os}. Assuming memory size is 1024MB.

 

1.3. Disk-Based Flow Control
默认情况,如果剩余磁盘空间在 1GB 以下,RabbitMQ 主动阻塞所有的生产者。这个阈值也是可调的。
 
二,Apache ActiveMQ 的流量控制
http://activemq.apache.org/images/activemq-logo.png
2.1. ActiveMQ 的生产者流量控制的触发条件有三个:
  • 不管 mq 有无做持久化配置:
    • !ActiveMQ所使用的内存到达 memoryUsage 配置值,默认值64MB;
  • 如果 mq 做了持久化配置:
    • !要打开了useCache开关,表明要将持久化消息缓存起来以便快速访问,默认是True;
    • !缓存在内存中消息总字节数到达 memoryLimit 配置值,默认值是1MB。
 
2.2. 触发之后会导致:
生产者调用发送消息函数时被Stuck(卡住)。
(注:关键词 activemq+stuck+producer  或 activemq+block+producer) 
 

一,基于信用证(Credit)的拥塞控制机制

1993 年,ATM领域开始寻找一种可以动态分配带宽并防止信元丢失的传输机制。因此提出了ABR(Available Bit Rate,可用比特率)业务,ABR 不强制网络为其分配固定的带宽,网络通过反馈信息动态调整分配给每个 ABR 连接的带宽。很多专家都投入到 ABR 业务的拥塞控制规范研究上。

基于 Credit 的方案由哈佛大学的H.T.Kung教授首先提出,采用链路级流控机制,以单一链路或虚电路VC作为基本的控制单位。每条链路有一个信元发送节点(可以是一个源端或一个交换节点)和一个接收节点(可以是一个交换节点或一个目的端系统),每个节点为每一条VC维持一个排队队列,信元接收端监视每条VC的排队队列长度,决定发送端可以发到VC上的信元数量(用信用证通知),信元发送端只能发送信用证值所允许的最大信元数量,如果只有一条VC,则信用证的值应足够大,以充分利用链路的带宽。一般来说,信用证值应满足下列条件:信用证值大于等于 链路信元速率乘以链路来回程传输时延。

http://course.cug.edu.cn/21cn/%BC%C6%CB%E3%BB%FA%CD%A8%D1%B6%CD%F8/FINISH/HTMLS/CONTENTS/CHAPTER6/neirong/402.files/image001.gif

6-17 给出了基于信用证拥塞控制机制的基本工作原理。信元接收方首先发送信用证到信元发送方,通知可用的缓冲区容量,发送方收到信用证之后,就可决定发送的信元数量。 

它的最大缺点是实现复杂,在每一对相邻的节点之间都需要维持这一信用证机制,同时也增加了信元的时延。

二,RabbitMQ 是如何实现的

『实质上 RabbitMQ 就是通过监控每个进程的mailbox,当某个进程负载过高来不及接收消息时,这个进程的mailbox就开始堆积消息。

当堆积到一定量时,就会阻塞住上游进程,让其不得接收新消息。从而慢慢上游进程的mailbox也开始积压消息。

到了一定的量又会阻塞上游的上游的进程接收消息,最后就会使得负责网络数据包接收的进程阻塞掉,暂停接收数据。

这就有点像一个多级水库,当下游水库压力过大时,上游水库就得关闭闸门,使得自己的压力也越来越大,需要关闭更上游的水库闸门,直到关闭最最上游的闸门。』——http://ybbct.iteye.com/blog/

1, http://www.rabbitmq.com/memory.html,RabbitMQ Flow Control
3, http://ybbct.iteye.com/blog/1562271,RabbitMQ流量控制机制简单分析
5,http://activemq.apache.org/producer-flow-control.html
6,http://working-with-activemq.blogspot.com/2012/05/performance-improvements.html 
7,http://stackoverflow.com/questions/5291679/activemq-topic-flooding
8,http://www.huaishao8.com/tag/activemq


© 著作权归作者所有

旁观者-郑昀
粉丝 100
博文 77
码字总数 162700
作品 0
朝阳
私信 提问
加载中

评论(1)

kongnanlive
kongnanlive
爬虫架构 | 消息队列应用场景及ActiveMQ、RabbitMQ、RocketMQ、Kafka对比

前言:在之前的业务中,使用了Kafka和RabbitMQ两种消息队列,这篇文章来做一个总结。 消息队列中间件是分布式系统中重要的组件,主要实现异步消息,应用解耦,流量削峰及消息通讯等功能。 下...

小怪聊职场
2018/04/26
0
0
ActiveMQ Kafka RabbtiMQ三者区别

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/j15533415886/article/details/90348048 目录 一、ActiveMQ ActiveMQ...

Live a happy life
05/19
0
0
消息中间件系列第2讲:如何进行消息队列选型?

要做技术选型,那么必须对现今的各个消息中间件有个深入的理解才能做技术选型。否则别人问你,你为什么要用这个消息中间件,你说不出个所以然来,怎么做架构师呢? 截止到目前为止,现在业界...

陈树义
01/07
0
0
ActiveMQ RabbitMQ KafKa对比

前言: ActiveMQ和 RabbitMq 以及Kafka在之前的项目中都有陆续使用过,当然对于三者没有进行过具体的对比,以下摘抄了一些网上关于这三者的对比情况,我自己看过之后感觉还 是可以的,比较清...

xiaomin0322
2018/05/11
375
0
架构设计之NodeJS操作消息队列RabbitMQ

一. 什么是消息队列? 消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。 消息队列(Message Queue)是一种应用间的通信方...

2018/07/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

XXL-JOB使用命令行的方式启动python时,日志过多导致阻塞的解决方式

一、Runtime.getRuntime().exec()的阻塞问题 这个问题也不能算是XXL-JOB的问题,而是Java的Runtime.getRuntime().exec()造成的,BufferedReader的缓冲区大小有限,当不能及时从缓冲区中把输出...

codeobj
6分钟前
1
0
java后端获取字符串标签里面的具体值

1、如下:怎么获取value值,使用Jsoup解决 <select id='department' name='department' class='select' tabindex='6' onchange='changeDept()'><option value=''>院系</optio......

木九天
13分钟前
2
0
Xamarin图表开发基础教程(10)OxyPlot框架支持的图表类型

Xamarin图表开发基础教程(10)OxyPlot框架支持的图表类型 OxyPlot组件支持26种图表,这些图表按照功能和样式可以分为4大类,分别为线型图表、条型图表、金融图表和其它图表。 线型图表 OxyP...

大学霸
17分钟前
2
0
移动端input“输入框”常见问题及解决方法

移动端input“输入框”常见问题及解决方法 1. ios中,输入框获得焦点时,页面输入框被遮盖,定位的元素位置错乱: 当页input存在于吸顶或者吸底元素中时,用户点击输入框,输入法弹出后,fie...

tyou
18分钟前
2
0
初探Android线程池

前言 最近在看OkHttp的源码,看的时候发现有关线程池的运用,自己就仔细想了一下,这个块知识好像不是很牢固。没办法,再研究一下有关线程池的相关知识吧。学习就是一个查漏补缺的过程,最终...

二营长的意大利炮手
25分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部