文档章节

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

旁观者-郑昀
 旁观者-郑昀
发布于 2012/10/11 00:18
字数 1464
阅读 1649
收藏 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


© 著作权归作者所有

共有 人打赏支持
旁观者-郑昀
粉丝 99
博文 77
码字总数 162700
作品 0
朝阳
加载中

评论(1)

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

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

小怪聊职场
04/26
0
0
ActiveMQ RabbitMQ KafKa对比

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

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

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

07/13
0
0
rabbitMQ、activeMQ、zeroMQ、Kafka、Redis 比较

Kafka作为时下最流行的开源消息系统,被广泛地应用在数据缓冲、异步通信、汇集日志、系统解耦等方面。相比较于RocketMQ等其他常见消息系统,Kafka在保障了大部分功能特性的同时,还提供了超一...

xumaojun
05/06
0
0
消息队列属性及常见消息队列介绍

什么是消息队列? 消息队列是在消息的传输过程中保存消息的容器,用于接收消息并以文件的方式存储,一个队列的消息可以同时被多个消息消费者消费。分布式消息服务DMS则是分布式的队列系统,消...

中间件小哥
06/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

qduoj~前端~二次开发~打包docker镜像并上传到阿里云容器镜像仓库

上一篇文章https://my.oschina.net/finchxu/blog/1930017记录了怎么在本地修改前端,现在我要把我的修改添加到部署到本地的前端的docker容器中,然后打包这个容器成为一个本地镜像,然后把这...

虚拟世界的懒猫
40分钟前
1
0
UML中 的各种符号含义

Class Notation A class notation consists of three parts: Class Name The name of the class appears in the first partition. Class Attributes Attributes are shown in the second par......

hutaishi
51分钟前
0
0
20180818 上课截图

小丑鱼00
今天
1
0
Springsecurity之SecurityContextHolderStrategy

注:下面分析的版本是spring-security-4.2.x,源码的github地址是: https://github.com/spring-projects/spring-security/tree/4.2.x 先上一张图: 图1 SecurityContextHolderStrategy的三个......

汉斯-冯-拉特
今天
0
0
LNMP架构(Nginx负载均衡、ssl原理、生成ssl密钥对、Nginx配置ssl)

Nginx负载均衡 网站的访问量越来越大,服务器的服务模式也得进行相应的升级,比如分离出数据库服务器、分离出图片作为单独服务,这些是简单的数据的负载均衡,将压力分散到不同的机器上。有时...

蛋黄_Yolks
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部