訊息佇列在日常開發中比較常用的開發中介軟體,每家大廠一般都會具有自己的訊息佇列伺服器。本文主要講述Python中如何使用RocketMQ的相關SDK。希望大家在閱讀本文前可以先了解一下RocketMQ的基本知識。
使用 pip install rocketmq -i https://pypi.tuna.tsinghua.edu.cn/simple 可以下載到rocketmq所需要的包(需要注意到的是RocketMQ是基於java寫的C/S架構服務,因此我們這安裝的僅僅是客戶端,也就是能夠連線到遠端的RocketMQ伺服器)。
1、消費者
看了前面“基本知識”之後,我們知道消費者消費資料的方式有兩種:1、主動呼叫從Broker伺服器拉訊息(pull)來使用,主動權在於程式。2、被動接收Broker伺服器推送(push)的訊息,主動權在Broker伺服器,一般是Brocker接收到了訊息就會可以傳導給消費者(也就是我們應用)。使用pull模式時,需要自己編寫邏輯來迴圈呼叫pull方法,並且處理可能出現的異常情況,例如網路問題或者佇列暫時沒有訊息可供消費的情況。因此我們一般是使用push模式,被動的接受Borker的資料並這是回撥函式(接受訊息後對訊息的處理函式)返回給Borker這條訊息消費情況。
消費資料我們需要明確,我們能夠接收到資料,需要有幾個必要的步驟:
- 建立消費者物件,建立時需要指明 消費組名稱
- 與RocketMQ的伺服器建立連線。
- 連線後需要進行身份驗證,可以選擇賬戶密碼驗證
- 指定消費者訂閱哪個Topic的訊息,並且指定訊息的回撥函式(回撥函式需要返回消費狀態:CONSUME_SUCCESS,RECONSUME_LATER)
完成上述操作之後,我們就可以使用消費者進行消費了,下面給出了兩種不同消費型別的消費者程式碼模板。
1.1、Push消費者
import time
from rocketmq.client import PushConsumer, ConsumeStatus
# 設定回撥函式來處理訊息
def call_back(msg):
# 需要使用msg.body來獲取內容
print(f"Received message: {msg.body.decode('utf-8')}")
# 在這裡編寫您的訊息處理邏輯
# ...
# 如果訊息處理成功,返回CONSUME_SUCCESS
# 如果訊息處理失敗,返回RECONSUME_LATER
return ConsumeStatus.CONSUME_SUCCESS
# 初始化消費者
consumer = PushConsumer('your_consumer_group')
# 使用 IP 和埠名稱設定伺服器地址
consumer.set_name_server_address("127.0.0.1:9887")
consumer.set_session_credentials("access_key", "secret_key", 'authChannel') # 完成設定驗證
# 訂閱Topic和過濾資訊
consumer.subscribe('topic名稱', call_back, '*')
# 啟動消費者, 此時會啟動新的現成, 消費者將一直執行, 直到主程序被停止
consumer.start()
# 在實際應用中,您可能需要新增邏輯來優雅地關閉消費者
try:
while True:
time.sleep(1000)
except KeyboardInterrupt:
pass
# 停止消費者
consumer.shutdown()
我們需要注意到的是consumer.start()會開啟新的執行緒持續監聽Brocker是否推送了新的訊息,這個消費執行緒需要一直被進行,因此這裡使用了while True迴圈保證主程序不結束(消費執行緒也就不會被kill,就算消費資料時出現了異常也會繼續監聽)。
1.2、Pull消費者
pull消費者與push消費者不同的是,不需要一直開啟一個執行緒去監聽,而是由程式作為主動方主動去獲取未消費資料
from rocketmq.client import PullConsumer # 初始化消費者(需要傳入消費組名稱) consumer = PullConsumer('your_consumer_group') # 使用 IP 和埠名稱設定伺服器地址 consumer.set_name_server_address("127.0.0.1:9887") consumer.set_session_credentials("access_key", "secret_key", 'authChannel') # 完成設定驗證 # 啟動消費者 consumer.start() # 從topic中拉取還未被消費的資料(consumer.pull返回的是可迭代物件) for msg in consumer.pull('YOUR-TOPIC'):
# 消費資料的邏輯在這裡 print(msg.id, msg.body) # 停止消費者 consumer.shutdown()
對於消費者需要注意的是:一個同名消費組只能監聽一個topic,因此如果想要使用多個topic的訊息,需要建立不同名的消費者。
2、生產者
對於生產者,其實與消費者類似也需要那四步必需步驟。只不過傳送的資訊需要使用Message物件來指定對應的topic,還需要注意的是傳遞的資料必須是字串,因此我們傳遞物件資料時需要用json.dumps轉換一下。
import json
from rocketmq.client import Producer
from rocketmq.client import Message
# 初始化生產者
producer = Producer('your_producer_group')
# 設定NameServer地址
producer.set_namesrv_addr('nameserver的address')
producer.set_session_credentials("access_key", "secret_key", 'authChannel') # 完成設定驗證
# 啟動生產者
producer.start()
# 構建訊息(需要將訊息傳送到指定Topic)
message = Message('your_topic')
# 設定訊息內容(注意訊息只能是字串)
msg_body = {"id":"test_id","name":"test_name","message":"test_message"}
message.set_body(json.dumps(msg_body).encode('utf-8'))
# 可以設定其他屬性,如Tags、Keys等
# message.set_tags('your_tag')
# message.set_keys('your_key')
try:
# 傳送訊息(此處就會傳送訊息到RocketMQ伺服器)
ret = producer.send(message)
# 列印傳送結果
if ret.status == Message.SendStatus.OK:
print("傳送成功")
else:
print(f"傳送失敗, 訊息狀態: {ret.status}")
except Exception as e:
# 處理傳送過程中可能出現的異常
print(f"Send message failed, exception: {e}")
finally:
# 停止生產者
producer.shutdown()
同一個生產者物件可以傳送多個Message物件,也就是說同一個生產者物件可以向多個topic傳送資訊。需要注意的是Message物件被髮送後,它通常不會被重新使用來傳送其他訊息,如果你想對同一個topic傳送多個資料需要建立新的Message物件。