RabbitMQ的流控机制

RabbitMQ的流控机制

消息发布

RabbitMQ是使用Erlang语言实现的,其中进程之间的通信是通过send发送消息来完成的。

当一个RabbitMQ实例运行时,就有数百个erlang进程交换消息来相互通信。例如,我们有一个reader进程从网络读取AMQP帧。这些帧被转换成AMQP命令,并被转发到AMQP的channel进程。这个channel进程需要向特定的exchange询问这个消息最终应该发往的queue列表。最后,如果AMQP消息需要持久化,则message store进程将接收它并将其写入磁盘
所以,当我们向RabbitMQ发布AMQP消息时,有如下erlang消息流:

reader process -> channel process -> exchange process -> message store process

上游的能够处理消息的数目,是通过下游在处理完消息之后返回的信用凭证来决定的,所以当这条链式消息流中某个进程达到性能瓶颈(右边是下游),必然导致上游所有的进程被阻塞

消费者消费速度

当生产者速度过高导致RabbitMQ队列堆积了大量消息,控流时RabbitMQ将阻塞新的生产者连接。主观上消费者消费速率应该至少保持不变,但实际是生产者和消费者的速度均受影响,且不平稳。

消费者消费速度降低,是因为:

由于队列现在接收的消息多于消费者可以应付的消息数量,因此与队列为空时(消息现在必须排队等待)相比,队列花费的CPU时间更多地处理每条消息。这会消耗驱动消费者的CPU时间,不幸的是,由于您选择了一台没有大量备用CPU容量的RabbitMQ机器,您开始最大化掏空CPU。因此,你的排队不能像以前一样艰难地推动你的消费者,这反过来又会增加队列的增长速度。这反过来又必须开始推送消息到磁盘,以释放内存,这反过来又占用了你本来就没有多少的CPU。 到此为止,你还能挣扎些什么呢?

解决办法: 那就是不要再继续生产了,赶紧让队列消耗完先

At this immediate point, you need to get your queues drained. Because your queues are spending more time dealing with new messages arriving than with pushing messages out to consumers, it’s unlikely that throwing more consumers at the queues is going to significantly help. You really need to get the publishers to stop.

而提高消费者消费速率的方法是:

  • 增加消费者数量
  • 使用批量Ack方式
  • 在实际生产环境中,建议针对每个要操作的queue,分别建立生产者线程和消费者线程。
    例如,A进程要向Q1、Q2、Q3队列生产消息,那么A进程要启动3个线程分别操作这3个队列,否则如果只使用1个线程1个connection向3个队列生产,当某一个队列流控时connection被阻塞,那么就会影响向其他队列生产的速度。对于消费者也是同样的道理。
  • 通过服务质量保障qos机制(同样可以用来做限流)来提高Prefetch count($channel->basic_qos(0, 100, false))
  1. rabbitmq对basic.qos信令的处理

首先,basic.qos是针对channel进行设置的,也就是说只有在channel建立之后才能发送basic.qos信令。

在rabbitmq的实现中,每个channel都对应会有一个rabbit_limiter进程,当收到basic.qos信令后,在rabbit_limiter进程中记录信令中prefetch_count的值,同时记录的还有该channel未ack的消息个数。

注:其实basic.qos里还有另外两个参数可进行设置(global和prefetch_size),但rabbitmq没有相应的实现。

  1. 队列中的消息投递给消费者时的处理

当rabbitmq要将队列中的一条消息投递给消费者时,会遍历该队列上的消费者列表,选一个合适的消费者,然后将消息投递出去。其中挑选消费者的一个依据就是看消费者对应的channel上未ack的消息数是否达到设置的prefetch_count个数,如果未ack的消息数达到了prefetch_count的个数,则不符合要求。当挑选到合适的消费者后,中断后续的遍历。

发布了48 篇原创文章 · 获赞 56 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/zhetmdoubeizhanyong/article/details/103215090