rabbitmq学习与分享(4)

一.前言

在上一篇文章中介绍了rabbitmq经过集群以及镜像队列的相关机制避免了broker的单点故障。可是有没有想过一个问题,若是消息的生产者比较多,或者发送消息的频率很快,或者消费者消费消息的速度很慢,是否是就会致使消息积压,可是内存或者磁盘空间是有限的啊,消息不断的积压,最后不会致使内存或者磁盘被撑爆么?本篇文章主要是针对这个问题,看看rabbitmq是如何处理的作一个学习分享。算法

整体而言,rabbitmq 提供了如下几种机制来避免这种状况的发生:网络

  • 内存预警
  • 磁盘预警
  • 流控

内存预警

rabbitmq 提供了内存预警的相关配置,也能够经过rabbitmqctl 客户端命令进行动态设置:,涉及到的相关参数以下:vm_memory_high_watermark(能够采用多种参数形式设置)学习

{vm_memory_high_watermark, 0.4} 
  {vm_memory_high_watermark, {absolute, 1073741824}}
  {vm_memory_high_watermark, {absolute, "1024M"}},
复制代码

一旦broker占用的内存超过这个阈值时,就会阻塞全部生产者的链接。spa

磁盘预警

rabbitmq 针对磁盘这块也设置了相应的预警参数:disk_free_limit也支持了几种参数形式的配置:code

{disk_free_limit, 50000000},
  {disk_free_limit, "50MB"},
  {disk_free_limit, {mem_relative, 2.0}}
复制代码

rabbitmq当内存吃紧时,一些非持久化的消息也会经过换页到磁盘。具体何时开始进行换页,能够经过参数{vm_memory_high_watermark_paging_ratio, 0.5} 进行设置.cdn

一旦broker占用的磁盘内存超过阈值时,也会阻塞全部的生产者链接。blog

流控

流控机制用来避免消息的发送速率过快致使难以支撑的情形,磁盘预警和内存预警至关于全局的流控,一旦达到这个预警值时就会阻塞全部的生产者链接。rabbitmq

针对单链接的流控:队列

rabbitmq流控机制原理实质上就是经过监控各erlang进程的mailbox,当某个进程负载太高来不及接收消息时,这个进程的mailbox就会开始堆积消息,当堆积到必定量时,就会阻塞住上游进程让其不得接收新消息,从而慢慢上游进程的mailbox也会开始积压消息,到了必定的量也会阻塞上游的上游的进程接收消息,最后就会使得负责网络数据包接收的进程阻塞掉,暂停接收数据。这就有点像一个多级的水库,当下游水库压力过大时,上游水库就得关闭闸门,使得本身的压力也愈来愈大这就须要关闭更上游的水库闸门直到关闭最最上游的闸门。进程

rabbitmq 采用credit 算法来实现这个过程的:

credit_from :表示能向下游发送多少消息,每发送一条,相应的value减一。 credit_to :表示能再接收多少消息,就向上游发送增长credit_from xx值.

当上游的发送频率高于下游的接收速率时,credit_from 的值就会逐渐被耗光,这时上游的发送进程就会阻塞,当上游收到下游发送的增长credit_from 值的通知时,上游就会解除阻塞,能继续发送消息。 这样就会将发送消息的速率限制在一个区间内,达到实现流控的目的。

总结

本文主要介绍了rabbitmq 流控实现的相关手段,参考资料以及相关的文档.

流控机制不只做用于connection ,也做用于channel,queue等等组件,具体的细节能够参考相应的文档和书籍资料进行进一步深刻学习。

相关文章
相关标签/搜索