RabbitMQ - Producer & Consumer 概念實作(Python)

前言

本篇會實作一個使用 RabbitMQ 的範例,運作過程如下方的示意圖。

示意圖

準備工作

安裝套件

python -m pip install pika --upgrade

用 docker 起一個 rabbitmq 的服務

docker run -d -p 5672:5672 -p 15672:15672 rabbitmq:3-management

模擬情境

描述

Producer 將會透過 RabbitMQ 傳送一段文字,並由 Consumer 印出原文及顛倒後的文字。

Producer

新增 send.py 並編輯檔案,用來當作 Producer 的角色。

touch send.py
code send.py

先建立一個 connection 到剛剛起的 RabbitMQ,這邊用的是 localhost,如果將來要連到別台機器,就改這邊就行了。接著 queue_declare 建一個名為 demoqueue

basic_publish() 將訊息丟到 exchange 裡,exhange會根據這項訊息上的 routing_key決定丟到哪個 queue

import pika
import sys

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.queue_declare(queue='demo')

text = ' '.join(sys.argv[1:]) or 'This is MQ demo text.'

channel.basic_publish(exchange='',
                      routing_key='demo',
                      body=text)
            
print(f" [x] Sent '{text}'")

connection.close()

Consumer

新增 receive.py 並編輯檔案,用來當作 Consumer 的角色。

touch receive.py
code receive.py

queue_declare 建一個名為 demoqueue,如果已經存在則不會重複建立。

其中的 callback 用來實現印出文字和顛倒文字的功能。

import pika, sys, os

def main():
    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
    channel = connection.channel()

    channel.queue_declare(queue='demo')

    def callback(ch, method, properties, body):
        print(f" [x] Received {body}")
        print(f" Original: {body}")
        print(f" Reversed: {body[::-1]}")

    channel.basic_consume(queue='demo', on_message_callback=callback, auto_ack=True)

    print(' [*] Waiting for messages. To exit press CTRL+C')
    channel.start_consuming()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print('Interrupted')
        try:
            sys.exit(0)
        except SystemExit:
            os._exit(0)

運作過程

打開兩個 terminal,一個先跑 receive.py,另一個跑 send.py,分別代表 Consumer 和 Producer。

結果如下,當 Producer 送出 message 而沒有搭配文字,這是會印出預設文字 This is MQ demo text. 和文字的顛倒。

接著再送出訊息搭配 Such a good day,同樣能夠使用。

Producer

(test) peter.yang@ycy-mac hello-world % python send.py
 [x] Sent 'This is MQ demo text.'
(test) peter.yang@ycy-mac hello-world % python send.py Such a good day
 [x] Sent 'Such a good day'

Consumer

(test) peter.yang@ycy-mac hello-world % python receive.py
 [*] Waiting for messages. To exit press CTRL+C
 [x] Received b'This is MQ demo text.'
 Original: b'This is MQ demo text.'
 Reversed: b'.txet omed QM si sihT'
 [x] Received b'Such a good day'
 Original: b'Such a good day'
 Reversed: b'yad doog a hcuS'

參考資料

https://pika.readthedocs.io/en/stable/modules/channel.html https://www.rabbitmq.com/tutorials/tutorial-one-python.html

Tags:
# python
# rabbitmq
# queue
# message queue