RabbitMQのMQTT Adapterを使ってみる


業務でRabbitMQのMQTT Adapterを使う必要が出てきたので、勉強がてらにこれらの動作確認を行った際の備忘録です。

※RabbitMQ?MQTT?なにそれ?という状態からのスタートでしたので、かなり初歩的なことしか確認してないです。m(_ _)m

<やりたかったこと>
Ubuntu上のRabbitMQの任意のqueueに、MacPC上でpublish(MQTT)したメッセージを格納する

<動作環境>

  • Mac
    OS: 10.13.6
    python: 3.5.2 (MQTT publishの実装で使用)

  • Ubuntu
    OS: 16.04
    RabbitMQ: 3.7.7
    ※UbuntuはMac上のVirtualBox上で動作してます(VirtualBoxはブリッジアダプターとして動作)

1.Ubuntu上にRabbitMQをインストール

Ubuntu上にRabbitMQをインストール方法自体は、検索すれば色々ヒットするので割愛
私の場合は以下のサイトを参考にインストールしました。
参考サイト

※上から順番にコマンドをポチポチすればOK

2.RabbitMQのMQTT Adapterの有効化

参考サイト(本家)

以下のコマンドを入力する


sudo rabbitmq-plugins enable rabbitmq_mqtt

プラグイン適用に成功すると、こんなメッセージが出てくるはず

The following plugins have been enabled:
  rabbitmq_mqtt

started 1 plugins.

3.MQTT動作確認用にテストアカウントを作成

以下のコマンドでアカウントを作成

# username and password are both "mqtt-test"
rabbitmqctl add_user mqtt-test mqtt-test  #第一引数がuser, 第二引数がpassword
rabbitmqctl set_permissions -p / mqtt-test ".*" ".*" ".*"
rabbitmqctl set_user_tags mqtt-test management

※当初、初期アカウント(user:guest/password:guest)で、Mac側から動作確認をしようとしたが、MQTTのconnectionをはろうとしていたがエラーで弾かれていた。そのため、別のアカウントを用意しました。ちなみに以下のエラーが出力されてました

2018-09-08 15:29:14.475 [info] <0.562.0> MQTT vhost picked using plugin configuration or default
2018-09-08 15:29:14.476 [warning] <0.562.0> MQTT login failed for "guest" access_refused (access must be from localhost)
2018-09-08 15:29:14.477 [info] <0.562.0> MQTT protocol error connect_expected for connection 192.168.43.39:53179 -> 192.168.43.126:1883

公式サイトに以下の記載があるのを見落としてましたね。。。

When an MQTT client provides no login credentials, the plugin uses the guest account by default which will not allow non-localhost connections.

4.MQTT Adapterの設定をconfigに記載

公式サイトの設定をほとんどパクりました。
変更した点は以下
「default_user」と「default_pass」を#3で作成したアカウントに変更
「exchange」をamq.fanoutに変更(デフォルトで用意されているfanoutのexchange)

/etc/rabbitmq/rabbitmq.config

 {rabbitmq_mqtt, [{default_user,     <<"mqtt-test">>},
                  {default_pass,     <<"mqtt-test">>},
                  {allow_anonymous,  true},
                  {vhost,            <<"/">>},
                  {exchange,         <<"amq.fanout">>},
                  {subscription_ttl, 1800000},
                  {prefetch,         10},
                  {ssl_listeners,    []},
                  {tcp_listeners,    [1883]},
                  {tcp_listen_options, [{backlog,   128},
                                        {nodelay,   true}]}]}

※上記ファイルについてですが、私の環境ではインストールした段階では作成されていなかったので、以下のファイルを解凍して上記のパスに配置しました。
/usr/share/doc/rabbitmq-server/rabbitmq.config.example.gz

設定が完了したらRabbitMQを再起動する

sudo systemctl restart rabbitmq-server.service

5.MQTT publish受信用のqueueを作成

RabbitMQの管理用画面をwebブラウザで開く
デフォルトでは、http://localhost:15672/で開く

①Adminアカウントでログイン(デフォルトはguest/guest)

②Queueタブを選択
③任意のQueue名を入力
④Add queueをクリック(※他のパラメータはデフォルトのまま)

⑤Queueが追加されていることを確認

⑥先ほど追加したQueueを選択し、「amq.fanout」をバインドする
※amq.fanoutはfanoutのexchangeのため、他のパラメータの設定は不要

これで、exchangeとqueueのバインドが完了しました

RabbitMQ側の準備は一旦これで完了です

6.MQTT publishを行うpythonスクリプトの作成

こちらはMac側で行いました
paho-mqttを使用して、MQTTのpublisherを作成しますので、
pip インストールでpaho-mqttを落としておきました

以下のコマンドを入力

pip install paho-mqtt

作成したpythonスクリプトは以下になります

mqtt_publish.py

import paho.mqtt.client as mqtt

host = 'xxx.xxx.xxx.xxx' #UbuntuのIPアドレスを設定してください
port = 1883
topic = 'amq.fanout'

jsonString = '''
{
    "device_A": {
        "data1": 45,
        "data2": 60,
        "data3": 90
    }
}
'''

client = mqtt.Client(protocol=mqtt.MQTTv311)

client.connect(host, port=port, keepalive=60)

# メッセージ(jsonString)をpublishします
client.publish(topic, jsonString)

client.disconnect()

6.Publishを実行

以下のコマンドを入力して実行

python mqtt_publish.py

<結果>
作成したキューにメッセージが格納されてるっぽい。

メッセージの中身も確認できました!

以上

今後の課題

1.MQTTにて、fanout以外のexchangeでメッセージをQueueに格納するにはどうすれば良いのか?
※今後時間があれば調査したいと思います。情報お持ちの方いらっしゃったらご教示いただけると嬉しいです。。