delhi09の勉強日記

技術トピック専用のブログです。自分用のメモ書きの投稿が多いです。あくまで「勉強日記」なので記事の内容は鵜呑みにしないでください。

RabbitMQのチュートリアルをやってみる(その2)

概要

前回に引き続きRabbitMQのチュートリアルをやってみる。

今回はチュートリアル1の「"Hello World!"」をやる。

www.rabbitmq.com

やったこと

RabbitMQに接続する

まずはRabbitMQに接続する。

チュートリアル上のコードは以下となっているが、RabbitMQにID/PASSWORDを設定している場合は、これだけだと認証エラーになってしまう。

import pika

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

エラー

pika.exceptions.ProbableAuthenticationError: ConnectionClosedByBroker: (403) 'ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.'

以下のように認証情報を渡す必要がある。

import pika

credentials = pika.PlainCredentials("admin", "password")
connection = pika.BlockingConnection(
    pika.ConnectionParameters("localhost", 5672, "/", credentials)
)
channel = connection.channel()
connection.close()

※ 公式ドキュメントは以下
pika.readthedocs.io

キューを作成する

以下で「hello」という名前のキューを作成する。
※ 事前にRabbitMQにキューを作成しておく必要はない。

channel.queue_declare(queue="hello")

以下のように、管理画面上でキューが作成されていることを確認できる。

f:id:kamatimaru:20210627002803p:plain

メッセージを送信する

以下で「Hello World!」というメッセージをキューに送信する。

channel.basic_publish(exchange="", routing_key="hello", body="Hello World!")

以下のように、管理画面上でメッセージを確認できる。

f:id:kamatimaru:20210627004704p:plain

メッセージを受信する

次にメッセージを受信する側のコードを書く。
別のPythonファイルに以下を書いて実行すると、プロセスが実行中の状態になる。

import pika

credentials = pika.PlainCredentials("admin", "password")
connection = pika.BlockingConnection(
    pika.ConnectionParameters("localhost", 5672, "/", credentials)
)
channel = connection.channel()
channel.queue_declare(queue="hello")

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)

channel.basic_consume(queue="hello", on_message_callback=callback, auto_ack=True)
channel.start_consuming()

この状態で、別のターミナルなどからメッセージを送信すると、メッセージがコンソール上に出力される。

$ python receive.py
 [x] Received b'Hello World!'
 [x] Received b'Hello World!'
 [x] Received b'Hello World!'

また、管理画面上でキュー上のメッセージは空になってることを確認できる。

f:id:kamatimaru:20210627005647p:plain

その他に試してみたこと

チュートリアルにはないが以下を試してみた。

送信側のqueue_declareのキュー名を変える。

送信側のqueue_declareのキュー名を以下のように変えてみた。

channel.queue_declare(queue="hello2")

メッセージ送信先のキューと受信側が待ち受けているキューが違うので、受信側はメッセージを受信できなくのではないかと予想していたが、結果はメッセージを受信した。

ドキュメントをよく読むと、queue_declareがやることは以下の2つとのことだった。

  • キューが存在するかチェックする。
  • キューが存在しなければ作成する。

Declare queue, create if needed. This method creates or checks a queue.

pika.readthedocs.io

従って、「どのキューにメッセージを送信するか」を指定しているのはqueue_declareではなかった。

「どのキューにメッセージを送信するか」を指定しているのは、basic_publishrouting_keyの方だった。

The queue name needs to be specified in the routing_key parameter.

routing_keyのキュー名を変える。

上記を踏まえて、basic_publishrouting_keyのキュー名を以下のように変更してみた。

channel.basic_publish(exchange="", routing_key="hello2", body="Hello World!")

今度は予想通り、受信側はメッセージを受信できなかった。

尚、存在しないキュー名を指定しても特にエラーは発生しなかったが、これは「存在しないキューに送られたメッセージは捨てられる」というRabbitMQの仕様らしい。

If we send a message to non-existing location, RabbitMQ will just drop the message.

stackoverflow.com

以上