初识RabbitMQ消息队列
介绍
RabbitMQ是一款基于网络通信的软件,有服务端和客户端。它基于Erlang语言开发,遵循AMQP协议。
RabbitMQ是一个消息队列,即消息中间件,它能够在应用程序之间提供可靠的消息传输。在易用性,扩展性,高可用性上表现优秀。
使用消息中间件利于应用程序之间的解耦,生产者(客户端)无需知道消费者(服务端)的存在。而且两端可以使用不同的语言编写,大大提供了灵活性。
Python连接RabbitMQ,需要借助pika
模块;pika模块是第三方模块,使用pip安装。
使用先要先安装RabbitMQ,安装RabbitMQ要先安装Erlang的环境。安装请参考B站视频(Linux)。
概念
- 生产者,发送数据的一端即生产者
- 队列,是一个媒介,生产者的数据要通过队列传给给消费者
- 消费者,结束数据的一端。
- 生产者和消费者的身份不是固定的;且生产者、消费者、队列三者可以在不同的主机上。
简单模式
简单模式下,生产者往队列中发消息后,结束本次操作。消费者会一直监听队列,等待数据,并进入监听循环状态。
实现简单模式,生产者需要做三件事
- 连接RabbitMQ,默认本地连接
- 建立队列,如果队列已经存在则直接使用
- 往队列中放消息
import pika
# 第一步,连接rabbitmq
parameters = pika.ConnectionParameters(host='localhost') # 默认本地rabbitmq的连接
connection = pika.BlockingConnection(parameters)
channel = connection.channel()
# 第二步,建队列
channel.queue_declare(queue='hello')
# 第三步,发消息
channel.basic_publish(exchange='', routing_key='hello', body='Hello World!')
print(" [x] Sent 'Hello World!'")
# 主动关闭连接
connection.close()
实现简单模式,消费者需要做三件事
- 连接RabbitMQ,默认本地连接
- 建立队列,
- 监听队列,等待数据,没有数据时阻塞等待
import pika
# 第一步,连接rabbitmq
parameters = pika.ConnectionParameters(host='localhost') # 默认本地rabbitmq的连接
connection = pika.BlockingConnection(parameters)
channel = connection.channel()
# 第二步,建队列
channel.queue_declare(queue='hello')
# 处理消息的回调函数
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
# 设置监听队列的参数,接收到消息后交给回调函数执行
channel.basic_consume(
queue='hello', on_message_callback=callback, auto_ack=True)
# 第三步,开启队列监听,进入监听循环
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
补充
-
消费者之所以再次建立队列的原因:消费者和生产者两方,任意一方都可能先开启程序;如果消费者先开启程序时生产者还没开启,此时是没有队列的,容易报错。执行
channel.queue_declare(queue='hello')
语句时,只会当队列hello不存在时才建立,如果队列hello存在,则直接使用不再重复建立。即开启的一端建立这个队列,后开启的只使用。且这个队列名是两端事先商定的,不能随意改变。 -
此时多个消费者如果在同时监听,采用轮询的方式获取队列中的消息。
-
可以在终端里查看消息队列的个数
sudo rabbitmqctl list_queues # linux
rabbitmqctl.bat list_queues # windows
-
其实,RabbitMQ中所有的消息都不是直接交给队列的,而是经过交换机。现在的简单模式,生产者发布时使用的参数exchange=''比较特殊,以后再补充。
-
如果连接的RabbitMQ在远程主机上,比如在阿里云服务器上,需要单独设置连接参数;且需要设置阿里云的安全组,开放端口号5672
import pika # 远程rabbitamq的连接配置 credentials = pika.PlainCredentials('用户名', '密码') parameters = pika.ConnectionParameters( host='远程主机公网ip', port=5672, virtual_host='/', credentials=credentials) connection = pika.BlockingConnection(parameters) channel = connection.channel() channel.queue_declare(queue='hello') ...