RabbitMQ在python開發中的應用

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個或多個單詞
  • *表示只能匹配 一個 單詞

這種模式由於用得比較少,這裏不再贅述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章