1. pika的安裝
Pika是Python的RabbitMQ(AMQP 0-9-1)客戶端庫,相當於pymysql在python中的作用,主要負責連接RabbitMQ。
具體文檔可見官網:https://pypi.org/project/pika/
安裝pika:
pip install pika
2. RabbitMQ[簡單模式]
簡單模式的重要參數(其它模式也適用):
消費者
auto_ack=True # 消費者一旦接收到完整任務,隊列裏的任務就會刪除
auto_ack=False # 消費者必須正確處理完任務後,發送下方回執信息,隊列裏的任務纔會刪除(造成擁塞)
ch.basic_ack(delivery_tag = method.delivery_tag) #當上面爲false 時,告訴生產者任務執行完成
生產者
channel.queue_declare(queue='hello', durable=True) # 消息持久化
properties=pika.BasicProperties(delivery_mode=2,)
消費者
channel.basic_qos(prefetch_count=1) # 表示誰處理完了誰就來取,不再按照順序依次來取
生產者發送消息到隊列中:
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters( host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello',durable=True)
channel.basic_publish(exchange='',
routing_key='hello',
body='認識你自己',
properties=pika.BasicProperties(delivery_mode=2,))
print(" [x] Sent '認識你自己'")
connection.close()
消費者從隊列中取出消息:
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello',durable=True)
def callback(ch, method, properties, body):
print(" [x] Received %r" % str(body,encoding ='utf8'))
ch.basic_ack(delivery_tag = method.delivery_tag)
channel.basic_qos(prefetch_count=1)
channel.basic_consume('hello',
callback,
False)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
3. RabbitMQ[exchange模式]
發佈訂閱 |
發佈訂閱和簡單的消息隊列區別在於,發佈訂閱會將消息發送給所有的訂閱者(消費者),而消息隊列中的數據被消費一次便消失。所以,RabbitMQ實現發佈和訂閱時,會爲每一個訂閱者創建一個隊列,而發佈者(生產者)發佈消息時,會將消息放置在所有消費者訂閱的相關隊列中。
生產者發送消息到交換機中:
import pika
# 連接rabbitmq服務器
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='logs', # 聲明一個名爲logs的交換機
exchange_type='fanout')
message = "理解他人"
向交換機發送數據message
channel.basic_publish(exchange='logs',
routing_key='',
body=message)
print(" [x] Sent %r" % message)
connection.close()
消費者創建隨機隊列綁定交換機,並從隊列中獲取消息:
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='logs',
exchange_type='fanout')
# 聲明一個隨機隊列
result = channel.queue_declare('',exclusive=True)
# 獲取隊列名稱
queue_name = result.method.queue
# 爲創建好的隨機隊列綁定一個名爲logs的交換機
channel.queue_bind(exchange='logs',
queue=queue_name)
print(' [*] Waiting for logs. To exit press CTRL+C')
def callback(ch, method, properties, body):
print(" [x] %s" % str(body,encoding='utf8'))
channel.basic_consume(queue=queue_name,
on_message_callback=callback,
auto_ack=True)
channel.start_consuming()
關鍵字 |
之前事例,發送消息時明確指定某個隊列並向其中發送消息,RabbitMQ還支持根據關鍵字發送,即:隊列綁定關鍵字,發送者將數據根據關鍵字發送到消息exchange,exchange根據關鍵字判定應該將數據發送至指定隊列。
生產者指定消息
import pika
import sys
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='direct_logs',
exchange_type='direct')
message = "理解他人"
channel.basic_publish(exchange='direct_logs',
routing_key='info', # 看這裏
body=message)
print(" [x] Sent %r" % message)
connection.close()
消費者監聽不同的關鍵字:
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='direct_logs',exchange_type='direct')
result = channel.queue_declare('',exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='direct_logs',
queue=queue_name,
routing_key='info') # 看這裏
print(' [*] Waiting for logs. To exit press CTRL+C')
def callback(ch, method, properties, body):
print(" [x] %r:%s" % (method.routing_key, str(body,encoding='utf8')))
channel.basic_consume(queue=queue_name,
on_message_callback=callback,
auto_ack=True)
channel.start_consuming()
模糊匹配 |
在topic類型下,可以讓隊列綁定幾個模糊的關鍵字,之後發送者將數據發送到exchange,exchange將傳入”路由值“和 ”關鍵字“進行匹配,匹配成功,則將數據發送到指定隊列。
- #表示可以匹配 0個或多個單詞
- *表示只能匹配 一個 單詞
這種模式由於用得比較少,這裏不再贅述