RabbitMQ的负载均衡

647 阅读2分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

前言:  首先你需要安装RabbitMQ在您的本地,端口设置为5672. 如果使用不同的主机端口则配置需要调整。前文讲到了消息的持久化。本篇文章我们来讲调度中心

负载均衡

您可能已经注意到,消费者仍然不能完全按照我们要求工作。例如,在两名消费者的情况下,当所有的消息都很多或者很少时,一个消费者会经常忙,而另一个消费者几乎不会做任何工作。嗯,RabbitMQ对此一无所知,仍然会均匀地发送消息。

这是因为 RabbitMQ 只是在消息进入队列时发送消息。它不查看未为消费者确认的消息数量。它只是盲目地向第 n 位消费者发送每一条消息。

我们需要做一些更改来让它实现负载均衡,我们可以使用通道#basic_qos通道方法与prefetch_count+1设置。这使用基本.qos协议方法告诉RabbitMQ不要一次给消费者一个以上的消息。或者,换句话说,在消费者处理并确认上一条消息之前,不要向其发送新消息。相反,它会将其发送给下一个不忙的消费者。

channel.basic_qos(prefetch_count=1)
#!/usr/bin/env python
import pika
import sys

connection = pika.BlockingConnection(
    pika.ConnectionParameters(host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='task_queue', durable=True)

message = ' '.join(sys.argv[1:]) or "Hello World!"
channel.basic_publish(
    exchange='',
    routing_key='task_queue',
    body=message,
    properties=pika.BasicProperties(
        delivery_mode=2,  # make message persistent
    ))
print(" [x] Sent %r" % message)
connection.close()
#!/usr/bin/env python
import pika
import time

connection = pika.BlockingConnection(
    pika.ConnectionParameters(host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='task_queue', durable=True)
print(' [*] Waiting for messages. To exit press CTRL+C')


def callback(ch, method, properties, body):
    print(" [x] Received %r" % body.decode())
    time.sleep(body.count(b'.'))
    print(" [x] Done")
    ch.basic_ack(delivery_tag=method.delivery_tag)


channel.basic_qos(prefetch_count=1)
channel.basic_consume(queue='task_queue', on_message_callback=callback)

channel.start_consuming()

注意:

如果消费者的负载已经足够多了,这个时候再给他们发消息其实也消费不掉。这种情况下增加消费者节点才是最好的选择。