お金をかけずにサーバーの勉強をしよう

RabbitMQでメッセージを受け渡し

2022年8月19日

メニューへ戻る

大きな企業さんとなると、社内システムが1つということもなく、各業務用のシステムが乱立していたりします。

しかし一つの会社ゆえ、個々の業務システムで扱っているデータを他の業務システムで使いたいとか、最後は基幹システムにデータを集めてきたい、そんな要件があることがほとんどでしょう。

システム間のデータの受け渡し方には色々なやり方がありますが、分かりやすいところでは以下の3つになるでしょう。

それぞれメリット・デメリットがありますので、簡単に私見を。

1.ファイルで渡す
比較的大きなデータをやり取りするときに使われる。
相手システムではファイルの作成や更新を検知する仕組みが必要。

2.自分のDBを見せる・相手のDBに書く
中間に何もないので無駄がないが、システム間連携が非常に密になってしまい、別システムなのに同一システムのよう。
DBのセキュリティ的によろしくない。

3.相手システムのAPIをたたく
小さなデータの場合に使う。
相手システムでAPIを実装していないとそもそも使えない。

とまぁ、こんな塩梅です。
どれが良くて悪いということではなく、適材適所で使っています。

ただどの方法でも、データを受け渡している以上はシステムの連携が強くなるのは避けられず、片方に障害があったとき、相手に障害の影響が及んでしまうのは永遠に解決しない課題と言って良いでしょう。


このシステム間の繋がりが密になることを避けるための方法の一つとして、メッセージキューと呼ばれる仕組みがあります。
メッセージキューの図

システムの間にメッセージ(データなら何でも良い)を保持してくれる中間的な存在を作り、両端にいるシステムの責任を限定してやることができます。

※当然メッセージキューが障害を起こしてしまえば、両端のシステムも巻き込まれてしまいますが、メッセージキューシステムは冗長化を行い滅多にサービスが止まらない形にするのが常套手段です。
「それなら両端のシステムを冗長化すればメッセージキューはいらないじゃん」という意見もありますが、システムの冗長化というのはお金がかかるもので、特にデータベースを抱えているサーバーを冗長化するのは大変にお金がかかります。
要件的に余り重要ではないシステムなのに、相手システムのために高い費用をかけて冗長化するというのもバランスが悪く、このような仕組みが求められる理由に繋がっていきます。

大分前提の話が長くなってきましたが、メッセージキューシステムとして Linuxで使えるものがあります。

RabbitMQ

こちら、あるキューイングのお作法(AMQP:Advanced Message Queuing Protocol)に沿って作られた OSSで、Linux界隈のキューイングシステムとしては有名です。


ではインストールしましょう。
環境は Ubuntu Server 22.04.1を使います。

Ubuntuのリポジトリに apt版も snap版もあるのですが、RabbitMQのサイトで「それらは古いので RabbitMQが用意したリポジトリからインストールしなさい」と言っていますのでそれに従います。

RabbitMQのサイトの記述ではまだ Ubuntu 22.04(Jammy)についての記述が無いのですが、もう対応版の準備はできているようなので、手順を Jammyに読み替えながらやります。


なお RabbitMQを実行する前提で Erlang(アーラン)という言語をインストールする必要がありますので一応触れておきます。

本家サイトはこちら。
Erlang

Erlangのインストールは、RabbitMQのインストール手順に含まれていますので後ほどまた。


RabbitMQのサイトの Ubuntu用のインストール手順はこちらです。
ちょっと分かり辛い記述なので、ここでは必要な要素だけを実行していきます。
Installing on Debian and Ubuntu

手順では、Cloudsmith と PackageCloud というリポジトリで最新版のパッケージを提供をしていると書いてあり、両方使うのかと思えばどうやら片方だけのようですので、手順で先に書いてあった PackageCloudの方でやってみます。

PackageCloudでのイントール手順はこちら。
Using RabbitMQ Apt Repositories on PackageCloud

PackageCloudからのパッケージダウンロードには apt-transport-httpsコマンドが必要なので、これをインストールします。

subro@UbuntuServer2204:~$ sudo apt-get install apt-transport-https
〜〜〜省略〜〜〜

インストールが問題なくできたとします。

PackageCloudが発行している公開鍵(GPGキー)を Ubuntu Serverに登録します。

subro@UbuntuServer2204:~$ curl -1sLf "https://keys.openpgp.org/vks/v1/by-fingerprint/0A9AF2115F4687BD29803A206B73A36E6026DFCA" | sudo gpg --dearmor | sudo tee /usr/share/keyrings/com.rabbitmq.team.gpg > /dev/null

subro@UbuntuServer2204:~$ curl -1sLf "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xf77f1eda57ebb1cc" | sudo gpg --dearmor | sudo tee /usr/share/keyrings/net.launchpad.ppa.rabbitmq.erlang.gpg > /dev/null

subro@UbuntuServer2204:~$ curl -1sLf "https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey" | sudo gpg --dearmor | sudo tee /usr/share/keyrings/io.packagecloud.rabbitmq.gpg > /dev/null

登録できました。
Team RabbitMQ・Launchpad PPA(Erlang用)・PackageCloudの GPGキーと書いてありました。

aptコマンドでインストールする時に見に行くリポジトリのリストに追加するため /etc/apt/sources.list.d/rabbitmq.list ファイルを作成します。
ピンク色の箇所が Ubuntuのバージョンに紐づく名前で、手順にある bionic(18.04)は jammy(22.04)に差し替えています。
上の段が Erlang、下の段が RabbitMQ のための記述です。

subro@UbuntuServer2204:~$ cat /etc/apt/sources.list.d/rabbitmq.list
# Source repository definition example.

## Provides modern Erlang/OTP releases
##
## "bionic" as distribution name should work for any reasonably recent Ubuntu or Debian release.
## See the release to distribution mapping table in RabbitMQ doc guides to learn more.
deb [signed-by=/usr/share/keyrings/net.launchpad.ppa.rabbitmq.erlang.gpg] http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy main
deb-src [signed-by=/usr/share/keyrings/net.launchpad.ppa.rabbitmq.erlang.gpg] http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy main

## Provides RabbitMQ
##
## "bionic" as distribution name should work for any reasonably recent Ubuntu or Debian release.
## See the release to distribution mapping table in RabbitMQ doc guides to learn more.
deb [signed-by=/usr/share/keyrings/io.packagecloud.rabbitmq.gpg] https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ jammy main
deb-src [signed-by=/usr/share/keyrings/io.packagecloud.rabbitmq.gpg] https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ jammy main

リポジトリの情報をアップデートします。

subro@UbuntuServer2204:~$ sudo apt-get update -y
ヒット:1 http://jp.archive.ubuntu.com/ubuntu jammy InRelease
ヒット:2 http://jp.archive.ubuntu.com/ubuntu jammy-updates InRelease
ヒット:3 http://jp.archive.ubuntu.com/ubuntu jammy-backports InRelease
ヒット:4 http://jp.archive.ubuntu.com/ubuntu jammy-security InRelease
取得:5 http://jp.archive.ubuntu.com/ubuntu jammy/main Translation-ja [295 kB]
取得:6 http://jp.archive.ubuntu.com/ubuntu jammy/universe Translation-ja [1,534 kB]
取得:7 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy InRelease [18.1 kB]
取得:9 http://jp.archive.ubuntu.com/ubuntu jammy/multiverse Translation-ja [7,160 B]
取得:8 https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu jammy InRelease [24.9 kB]
取得:10 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main Sources [1,860 B]
取得:12 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 Packages [7,376 B]
取得:11 https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu jammy/main amd64 Packages [4,001 B]
取得:13 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main Translation-en [5,140 B]
1,898 kB を 3秒 で取得しました (725 kB/s)
パッケージリストを読み込んでいます... 完了

できました。
パッケージのインストールをします。

Erlangから。

subro@UbuntuServer2204:~$ sudo apt-get install -y erlang-base \
                        erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \
                        erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \
                        erlang-runtime-tools erlang-snmp erlang-ssl \
                        erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了
状態情報を読み取っています... 完了
以下の追加パッケージがインストールされます:
  libsctp1
提案パッケージ:
  erlang erlang-manpages erlang-doc lksctp-tools
以下のパッケージが新たにインストールされます:
  erlang-asn1 erlang-base erlang-crypto erlang-eldap erlang-ftp erlang-inets erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key erlang-runtime-tools
  erlang-snmp erlang-ssl erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl libsctp1
アップグレード: 0 個、新規インストール: 18 個、削除: 0 個、保留: 0 個。
20.6 MB のアーカイブを取得する必要があります。
この操作後に追加で 32.1 MB のディスク容量が消費されます。
取得:1 http://jp.archive.ubuntu.com/ubuntu jammy/main amd64 libsctp1 amd64 1.0.19+dfsg-1build1 [9,370 B]
取得:2 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-base amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [10.2 MB]
取得:3 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-asn1 amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [946 kB]
取得:4 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-crypto amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [198 kB]
取得:5 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-public-key amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [797 kB]
取得:6 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-mnesia amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [927 kB]
取得:7 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-runtime-tools amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [262 kB]
取得:8 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-ssl amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [1,645 kB]
取得:9 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-eldap amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [161 kB]
取得:10 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-ftp amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [118 kB]
取得:11 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-tftp amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [137 kB]
取得:12 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-inets amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [654 kB]
取得:13 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-snmp amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [1,913 kB]
取得:14 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-os-mon amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [125 kB]
取得:15 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-parsetools amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [228 kB]
取得:16 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-syntax-tools amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [340 kB]
取得:17 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-tools amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [624 kB]
取得:18 http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu jammy/main amd64 erlang-xmerl amd64 1:25.0.4-1rmq1ppa1~ubuntu22.04.1 [1,413 kB]
20.6 MB を 46秒 で取得しました (447 kB/s)
以前に未選択のパッケージ erlang-base を選択しています。
(データベースを読み込んでいます ... 現在 73633 個のファイルとディレクトリがインストールされています。)
.../00-erlang-base_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-base (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-asn1 を選択しています。
.../01-erlang-asn1_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-asn1 (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-crypto を選択しています。
.../02-erlang-crypto_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-crypto (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-public-key を選択しています。
.../03-erlang-public-key_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-public-key (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-mnesia を選択しています。
.../04-erlang-mnesia_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-mnesia (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-runtime-tools を選択しています。
.../05-erlang-runtime-tools_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-runtime-tools (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-ssl を選択しています。
.../06-erlang-ssl_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-ssl (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-eldap を選択しています。
.../07-erlang-eldap_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-eldap (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-ftp を選択しています。
.../08-erlang-ftp_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-ftp (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-tftp を選択しています。
.../09-erlang-tftp_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-tftp (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-inets を選択しています。
.../10-erlang-inets_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-inets (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-snmp を選択しています。
.../11-erlang-snmp_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-snmp (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-os-mon を選択しています。
.../12-erlang-os-mon_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-os-mon (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-parsetools を選択しています。
.../13-erlang-parsetools_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-parsetools (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-syntax-tools を選択しています。
.../14-erlang-syntax-tools_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-syntax-tools (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-tools を選択しています。
.../15-erlang-tools_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-tools (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ erlang-xmerl を選択しています。
.../16-erlang-xmerl_1%3a25.0.4-1rmq1ppa1~ubuntu22.04.1_amd64.deb を展開する準備をしています ...
erlang-xmerl (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を展開しています...
以前に未選択のパッケージ libsctp1:amd64 を選択しています。
.../17-libsctp1_1.0.19+dfsg-1build1_amd64.deb を展開する準備をしています ...
libsctp1:amd64 (1.0.19+dfsg-1build1) を展開しています...
erlang-base (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
Searching for services which depend on erlang and should be started... none found.
erlang-xmerl (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-syntax-tools (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-parsetools (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-asn1 (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-tftp (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
libsctp1:amd64 (1.0.19+dfsg-1build1) を設定しています ...
erlang-mnesia (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-crypto (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-runtime-tools (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-tools (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-snmp (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-public-key (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-ssl (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-os-mon (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-eldap (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-ftp (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
erlang-inets (1:25.0.4-1rmq1ppa1~ubuntu22.04.1) を設定しています ...
libc-bin (2.35-0ubuntu3.1) のトリガを処理しています ...
man-db (2.10.2-1) のトリガを処理しています ...
Scanning processes...
Scanning linux images...

Running kernel seems to be up-to-date.

No services need to be restarted.

No containers need to be restarted.

No user sessions are running outdated binaries.

No VM guests are running outdated hypervisor (qemu) binaries on this host.

インストールできました。
2022年8月19日時点の最新版の 25.0.4が入りました。

RabbitMQのインストールです。

subro@UbuntuServer2204:~$ sudo apt-get install rabbitmq-server -y --fix-missing
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  rabbitmq-server
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。
12.9 MB のアーカイブを取得する必要があります。
この操作後に追加で 32.9 MB のディスク容量が消費されます。
取得:1 https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu jammy/main amd64 rabbitmq-server all 3.10.7-1 [12.9 MB]
12.9 MB を 3秒 で取得しました (4,363 kB/s)
以前に未選択のパッケージ rabbitmq-server を選択しています。
(データベースを読み込んでいます ... 現在 74738 個のファイルとディレクトリがインストールされています。)
.../rabbitmq-server_3.10.7-1_all.deb を展開する準備をしています ...
rabbitmq-server (3.10.7-1) を展開しています...
rabbitmq-server (3.10.7-1) を設定しています ...
グループ `rabbitmq' (GID 119) を追加しています...
完了。
システムユーザー `rabbitmq' (UID 114) を追加しています...
新しいユーザー `rabbitmq' (UID 114) をグループ `rabbitmq' に追加しています...
ホームディレクトリ `/var/lib/rabbitmq' を作成しません。
Created symlink /etc/systemd/system/multi-user.target.wants/rabbitmq-server.service → /lib/systemd/system/rabbitmq-server.service.
man-db (2.10.2-1) のトリガを処理しています ...
Scanning processes...
Scanning linux images...

Running kernel seems to be up-to-date.

No services need to be restarted.

No containers need to be restarted.

No user sessions are running outdated binaries.

No VM guests are running outdated hypervisor (qemu) binaries on this host.

インストールできました。
こちらも 2022年8月19日時点の最新版の 3.10.7が入りました。

この状態で RabbitMQはもう動いています。

インストール作業はこれで完了です。


RabbitMQを利用するプログラムを作りましょう。

データ送信元とデータ受信先のプログラムを作るにあたり、サーバー構成を以下のようにしたいのですが、
RabbitMQの構成図 1

実験環境には3つのサーバーOSを立てるメモリ的余裕がないので、RabbitMQをインストールしたサーバー内で全部やります。
RabbitMQの構成図 2

RabbitMQは今ある開発言語の色々なものに対応していますので Python3で作ります。

なお、入れるのと出すので同じ言語でなくても良く、入れるのは Pythonで、出すのは Javaでも OKです。

RabbitMQのサイトにPythonのチュートリアルがありますので、それをやりましょう。
Hello worldを送るチュートリアル(タイトルがありませんでした)

まず Pythonの RabbitMQライブラリを入れるようです。
「Pika」って言うんでしょうか、日本人にはこの名前はちょっと…ですが仕方ありません。

Ubuntu Server 22.04.1には pip3がインストールされていませんので、先にこれをインストールします。
結構色々とインストールされますが、そこは割愛します。

subro@UbuntuServer2204:~$ sudo apt install pip

pipが問題なく入ったとして、pika…のインストールをします。

subro@UbuntuServer2204:~$ python3 -m pip install pika --upgrade
Defaulting to user installation because normal site-packages is not writeable
Collecting pika
  Downloading pika-1.3.0-py3-none-any.whl (155 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 155.3/155.3 KB 3.3 MB/s eta 0:00:00
Installing collected packages: pika
Successfully installed pika-1.3.0

インストールできました。

チュートリアルにある送信側プログラム(send.py)はこのようなものです。
Ubuntu Server 22.04.1の環境で実行できるよう、1行目だけチュートリアルとは変えています。

subro@UbuntuServer2204:~/work/python$ cat send.py
#!/usr/bin/python3
import pika

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

channel.queue_declare(queue='hello')

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

print(" [x] Sent 'Hello World!'")

connection.close()

このチュートリアルのプログラムはスクリプトとして直接実行できる形になっているので、send.pyファイルに実行権限をつけてやります。

subro@UbuntuServer2204:~/work/python$ chmod 744 send.py

send.pyを実行します。

subro@UbuntuServer2204:~/work/python$ ./send.py
 [x] Sent 'Hello World!'

正常に実行されました。

この状態で RabittMQの中がどうなっているかというと、send.py が「hello」という名前のキューを作り、その中に「Hello World!」というメッセージを1つ入れました。
RabbitMQの構成図 3
大事なのは、受信側のプログラムがいようがいまいが、send.pyの仕事はこれで完了ということです。

チュートリアルはここで、キューの中を見に行っています。
rabbitmqctlコマンドを使いますが、root権限が必要なようなので、sudoも使って下さい。

subro@UbuntuServer2204:~/work/python$ sudo rabbitmqctl list_queues
Timeout: 60.0 seconds ...
Listing queues for vhost / ...
name    messages
hello   1

ピンク色の箇所に「hello」という名前のキューに、1つメッセージがあることを表しています。

続いて、受信側のプログラム(receive.py)を作ります。

subro@UbuntuServer2204:~/work/python$ cat receive.py
#!/usr/bin/python3
import pika, sys, os

def main():
    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
    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)

    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)

receive.pyに実行権限を付けて、実行します。

subro@UbuntuServer2204:~/work/python$ chmod 744 receive.py

subro@UbuntuServer2204:~/work/python$ ./receive.py
 [*] Waiting for messages. To exit press CTRL+C
 [x] Received b'Hello World!'

ピンク色の行が「Hello World!」というメッセージを受信したことを表しています。

このプログラムはずっとキューに次のデータが入ってくるのを待っているので、Ctrl+cで終了させます。

このプログラムは図ではこの箇所になります。 RabbitMQの構成図 4
やはり、送信側のプログラムがいない状態であることが重要です。


2つのプログラムがキューを間に入れることによって非同期にデータの受け渡しができるのが分かって頂けたでしょうか。

この「非同期」という方法の効果はすぐには理解できないと思いますが、こういうシステムの設計をちょっとやってみれば理解できます。

ここで環境を構築するのは大変でしたが、プログラムから利用するのは非常に簡単であることも特筆する点です。

キューイングはかなり強力な機能なんですが、これだけ簡単に扱えるようになっているのは凄いことですし、RabbitMQの機能はもっと複雑なこともできますので、OSSでここまでできるのかと感心するばかりです。


本番環境で RabbitMQを使う場合は冗長化構成を取ることが必須ですが、RabbitMQ自体に冗長化機能があります。

クラウドなんかですと、これと同じ機能をサービスとして提供していて、当然裏では冗長化されていますね。

実際にオンプレ環境で RabbitMQを使うことはなくとも、RabbitMQに触れることで、メッセージキューイングのコンセプトを理解できるようになると思います。


日本語書籍はゼロです! 更に電子書籍しかありません。

RabbitMQ Essentials Build distributed and scalable applications with message queuing using RabbitMQ, 2nd Edition【電子書籍】[ Lovisa Johansson ]

価格:2,496円
(2022/8/19 20:14時点)
感想(0件)

RabbitMQ Cookbook【電子書籍】[ Sigismondo Boschi ]

価格:3,177円
(2022/8/19 20:15時点)
感想(0件)