MQTTの運用や設計について調べてみる
概要
IoT機器等で使用されるPub/Sub型プロトコル、MQTT。運用や設計についてのノウハウが気になるところです。
本記事は、(雑記として)MQTTの運用や設計に関して調べた際のメモです。今後調べ直す機会があれば更新するかもしれません。
参考として、MQTTブローカーのMosquitto導入についてこちらの記事にまとめてあります。
本記事の目的
- MQTTの運用や設計に関する調査状況をメモしておく。
目次
基本
MQTTの構成と実装
MQTTを使用するシステムは、MQTTクライアント(Subscriber、Publisher)と、MQTTブローカーから構成されます。
フリーソフトやライブラリ、あるいはクラウドサービスとして、多くのMQTTの通信機能(ブローカー、クライアント)の実装があります(参考)。
IoT機器やそのゲートウェイ製品としても、MQTTによる通信を想定したものが多いです。
余談ですが、監視ソフトウェアのZabbixは、Zabbix Agent 2においてMQTTのSubscriberとして動作し取得したデータをZabbixサーバに送信する機能があります(機会があれば別途記事を掲載します)。
MQTT動作状況の確認
仮に、とあるシステムがMQTTを使用して動作中であるとして、その動作状況を把握したいケースを考えてみます。
どんなMQTTクライアントがいるかの確認
どんなMQTTクライアント(Publisher、Subscriber)が動作しているのか、確認する方法について調べた範囲でメモしておきます。
- Subscriberとしては、受信したメッセージ自体には、どのPublisherから送信されたものかの情報は無い。
- MQTTブローカーとしては、MQTTクライアントからクライアントID(thingId的なもの)を含むパケットを受信している。
以下のLWT機能は、MQTTクライアントを把握するための方法ではないですが補足として記載します。
- MQTTにはLWT(Last Will And Testament)、"遺言"的な意味の機能あり。
- MQTTブローカーは、意図しない原因でPublisherと通信できなくなった場合に、予めLWTに指定されたメッセージをSubscriberへ送信する。
- LWT機能を使用する場合、LWTメッセージはMQTTクライアントからのCONNECTメッセージ内で指定される。
- OASISの文書内の"3.1.3.2 Will Properties"などに記載あり("LWT"とは書かれていない)。
- LWTの動作説明は、mqtt.orgのFAQから参照可能(HiveMQの説明ページへのリンク)。
アクティブなトピックの確認
次に、どんなトピックのやり取りがされているのか、リアルタイムで確認する方法について調べた範囲でメモしておきます。
- MQTTとしては、アクティブなトピックの一覧を取得する方法自体は無さそう。
- MQTTクライアントで全トピックをサブスクライブし続けることで、実質的にアクティブなトピックを可能(参考)。
- Mosquittoでの実行例
mosquitto_sub.exe -h (MQTTブローカー) -t "#" -d
- -t "#"で全トピックを指定しサブスクライブ。-dにてデバッグ表示。全トピック(#)にPUBLISHされたメッセージを受信する。
- 上記コマンド実行時のメッセージ受信例:
Client null received PUBLISH (d0, q0, r0, m0, 'test/Topic1', ... (77 bytes))
- Mosquittoでの実行例
- その他、ネットワークトレースの取得等。
管理用トピック($SYSなど)
MQTTの動作状況を把握に役立ちそうな、管理用トピック(トピック名が$から始まるもの)というものがあるようです。ただ、細かく標準化はされていないようで、各ブローカーの実装次第のように思われます。
以下、Mosquittoでの確認例です。
`"c:\Program Files\mosquitto\mosquitto_sub.exe" -h (MQTTブローカー) -t "$SYS/broker/clients/active"` 2
上記の例では、アクティブなクライアント数が2であることが確認できます。
詳細
MQTTのトピック設計(メモ)
いくつか参考URLを記載します。
- AWS IoT Core の MQTT トピックの設計
AWSによるベストプラクティスの解説ホワイトペーパー(PDFへのリンクあり)。 - 参考サイト1
- 参考サイト2
以下、トピック設計に関するメモです。
- トピック名は"/"で区切られた階層構造
- 例:france/office/3F/temp、japan/factory/6F/humid
- ある区域内のデータは1つのトピックにして、その中で細分化する等も
- ワイルドカードサブスクリプション(#)の活用
- 以下AWSドキュメントのベストプラクティスより引用+メモ
- 複数データのトピックをどのようにまとめるか
- 1トピックに複数のデータを(JSON等で)まとめて送るかどうか。
- 温度トピック、湿度トピックのように、各データでトピックを分ける方法が基本と思われる。
- 同時に取得されたデータをまとめてセットで送受信することが重要なデータはまとめても良いかも。
- 1トピックに複数のデータを(JSON等で)まとめて送るかどうか。
- MQTTのトピック名の変換機能
- そのような機能は見当たらない。以下、メモ程度。
- 例えば、複数のセンサー(Publisher)が、同一トピックにPublishする構成の場合に、ブローカー側でPublisherごとにトピック名を変換(自動振り分け)し、Subscriberが各センサーごとにトピックを分けてデータ受信したりすることができたら便利かも。
- 参考:トピック名の変換が可能なMQTTブリッジ(詳細は未確認、クライアントIDを埋め込むことはできなさそう)