RabbitMQ优先队列-基于Python的pika模块

优先队列

RabbitMQ从3.5.0开始,可以实现优先队列的功能。

可以通过参数的设置创建优先队列,或者在RabbitMQ 的webUI界面中新建一个优先队列。

下面通过代码的方式创建优先队列。

两个操作

  • 创建队列时使用并设置参数:arguments={"x-max-priority": 10},参数值从1~255(整数)。
  • 发布消息时,使用pika.BasicProperties()的优先级字段priority发布优先消息 。数字越大表示优先级越高。

代码实现

因为生产者和消费者都涉及到连接和创建队列的操作,于是将其提取整合到一个公共的函数中

创建队列时,使用参数arguments,提供键x-max-priority和对应的值。

common.py

import pika

# 设置队列名和最高等级
queue_name = 'priority-queue'
max_priority = 10

def get_channel():
    # 连接RabbitMQ并获取频道
    parameters = pika.ConnectionParameters(host='127.0.0.1')
    connection = pika.BlockingConnection(parameters)
    channel = connection.channel()

    # 创建队列,设置最大优先级
    channel.queue_declare(
        queue=queue_name, arguments={"x-max-priority": max_priority}
    )
    return channel

发布消息时,发布消息时使用BasicProperties的字段priority

发布者.py

import sys, time, pika
import common


if __name__ == '__main__':

    # default priority 0
    priority = int(sys.argv[1]) if len(sys.argv) > 1 else 0

    channel = common.get_channel()
    queue_name = common.queue_name

    # 发布消息
    for i in range(5):
        message = 'message#{index}-with-priority{priority}'.format(
            index=i+1, priority=priority
        )
        # 发布消息时使用BasicProperties的字段priority
        channel.basic_publish(
            properties=pika.BasicProperties(priority=priority),
            exchange='',
            routing_key=queue_name,
            body=message
        )
        print("Published:", message)
        time.sleep(0.1)

消费者.py

import time

import common


def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)
    ch.basic_ack(delivery_tag=method.delivery_tag)

if __name__ == '__main__':
    channel = common.get_channel()
    queue_name = common.queue_name
    
    channel.basic_consume(queue=queue_name,
                          on_message_callback=callback)
    print(' [*] Waiting for messages. To exit press CTRL+C')
    channel.start_consuming()

补充

  • 当消费端的速度大于生产端的速度,且broker中没有消息堆积的话,对发送的消息设置优先级也没什么实际意义。
  • 因为发送端刚发送完一条消息就被消费端消费了,那么就相当于broker至多只有一条消息,即对单条消息来说优先级是没有意义的。
  • 参考博客1
  • 参考博客2
posted @ 2020-05-11 19:06  the3times  阅读(1210)  评论(0)    收藏  举报