Rabbitmq
1.引言
1.1什么是rabbitmq
RabbitMQ 是一个消息代理,它可以接受并转发消息。RabbitMQ集接受,存储转发为一体。TODO…
1.2消息队列的基本概念
可以把消息队列看为一个消息容器,我们可以按需生产消息向容器中发送或者从容器中消费消息,尽管这听起来想“一个人”完成的操作,但实际生产和消费的角色并不相同,而是两个程序,并且这两个程序往往不在同一机器上。
生产消息的一方我们通常称为“生产者”:
消费消息的一方通常称为“消费者”:
2.RabbitMQ 基础
2.1安装
我们将使用 Pika 1.0.0,它是 RabbitMQ 团队推荐的 Python 客户端。 要安装它,您可以使用 pip 软件包管理工具:
python -m pip install pika --upgrade
2.2"holle world"示例
我们将写两个简单的代码,一个作为生产者发送“holle world”字符串,一个作为消费者从队列接受字符串,并在屏幕上打印出来。
首先先来编写我们的生产者”sending.py“
#!/usr/bin/env python
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
我们这里是连接的本地的服务,如果想连接其他机器上的服务只需要更改“localhost”即可。
有了生产者(后续统一用P表示)之后我们就需要有一个队列来作为和消费者(后续统一用C表示)之间通信的媒介。
channel.queue_declare(queue='hello')
如果P向一个不存在的队列发送消息,那么该消息就会被丢弃。
需要注意的是Rabbitmq不会直接向队列发送消息,而是将消息发送给exchange(交换机),由exchange来通过绑定的规则向一个或多个队列发送消息。这部分的内容在3.1会有更多介绍。
我们现在只需要知道我们需要向默认的exchange发送消息即可,默认的exchange用“”
字符串来表示。
channel.basic_publish(exchange='', #交换机类型,这里采用默认的使用空字符串表示
routing_key='hello', # 队列名
body='Hello World!') #消息内容
print(" [x] Sent 'Hello World!'")
connection.close() #关闭连接
现在我们就可以向hello队列发送消息了,下面我们就来完成C的代码“receiving”。
同样的我们需要先和Rabbitmq取得连接
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello')
这里我们再一次创建了hello队列,不用担心调用多次queue_declare函数只会创建一个同名的队列,这样的好处就是当我们无法确定是sending.py在receiving.py之前运行的时候代码也不会报错,这时重复的创建队列就是一个好的方法,也推荐在实际应用中这样做。
接下来就是为receiving写一个回调函数(callback),该函数的作用就是在C取得队列中的消息之后,用过callback处理,我们这里比较简单就是打印接收的消息。
def callback(ch, method, properties, body):
print(f" [x] Received {
body}")
接下来就需要告诉这个callback函数从那个队列去接收消息。
channel.basic_consume(queue='hello',
auto_ack=True,
on_message_callback=callback)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
对于auto_ack=True参数,其实是Rabbitmq的确认应答机制,Rabbitmq需要知道C取得的消息是否被正确的处理了,就是通过该参数来控制,后序在3.2会有更多的介绍。
整合起来如下:
sending.py
#!/usr/bin/env python
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
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()
receiving
#!/usr/bin/env python
import pika, sys, os
def main():
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello')
def callback(ch, method, properties, body):
print