MQTTは、主にIoTやM2Mで利用されるプロトコルです。
本記事では、MQTTの概要と使い方について紹介します。
MQTTの概要と使い方について紹介します
- MQTTとは
- MQTTの仕組み
- MQTTの使い方
MQTTとは
MQTTは、主にIoTやM2Mで利用されているプロトコルです。
MQTTはIoT機器に最適で、軽量で少電力で動作することができます。
また非同期通信で、1対多の構成でも、利用することができます。
HTTPとの違い
Webのサーバー機能で利用されるのがHTTPです。
サーバー間のAPI連携であれば、HTTP/RESTで問題ありませんが、以下の場合には不向きです。
- 大量IoT機器の状態をリアルタイムで知りたい
- 回線が細いく不安定である
- 非力なデバイスを利用している
- 1対多構成で通信したい
MQTTは上記の問題を解決するために考案されたプロトコルです。
もともとは、1999年に、油田のパイプラインを衛星回線経由で監視するためにIBMが設計したプロトコルです。
| 項目 | HTTP | MQTT |
|---|---|---|
| 通信モデル | 要求 → 応答 | 発行 → 購読 |
| 接続 | リクエストごとに確立 | 常時接続を維持 |
| 送信の起点 | クライアントのみ | Broker経由でPublishが送信する |
| 宛先の指定 | URL | トピック |
| 最小ヘッダサイズ | 大 | 小 |
| 相手の数 | 基本1対1 | 1対多、多対多 |
MQTTの仕組み
MQTTは、Pub/Sub(Publish/Subscribe)モデルで動作する、軽量なメッセージングプロトコルです。
Broker(発行者)を立ち上げて、Publisher(発行者)がメッセージを送信し、Subscriber(購読者)がメッセージを受信します。
| 役割 | 説明 | 利用例 |
|---|---|---|
| Publisher(発行者) | メッセージを送る側 | センサー |
| Subscriber(購読者) | メッセージを受け取る側 | ダッシュボード、記録処理 |
| Broker(ブローカー) | 両者の間に立ち、メッセージを仲介するサーバー | – |
PublisherとSubscriberは、送信先や受信元を知らなくても、ブローカーを経由することで、メッセージを受信することができます。
Publisherは、トピック名とペイロードを指定して、メッセージを送信します。
Subscriberは、購読したいトピック名を指定して、メッセージを受信します。
Brokerを経由しているため、PublisherとSubscriberはお互いを知らなくても通信することができます。
PublisherとSubscriberが、疎結合な設計となっていることで、PublisherはSubscriberの数が増えてもソースコードを変更する必要がありません。
システム構成
[ センサーA ]--publish-->+
Publisher |
| sensor/room1/temp
[ センサーB ]--publish-->+---> [ Broker ] ---+--> [ ダッシュボード ]
Publisher (Mosquitto) | Subscriber
|
+--> [ アラート監視 ]
| Subscriber
|
+--> [ 記録用DB ]
SubscriberBrokerを経由して、メッセージを送受信します。 クライアント同士が直接つながることはありません。 Brokerは、受け取ったメッセージを、そのトピックを購読しているクライアント全員に配信します。
トピック
トピックは、メッセージの宛先を表す文字列です。
/で区切って階層構造を作ることもできます。
トピック例
home/livingroom/temperature
home/livingroom/humidity
home/bedroom/temperature
factory/line1/machine3/status事前に定義する必要はなく、Publisherがトピックが有効になります。
単一レベルワイルドカード(+)
購読するときだけ、ワイルドカードを利用することができます。(publishは利用不可)
単一レベルワイルドカードは、1階層だけにマッチします。
トピック例
home/+/temperature| トピック | マッチ有無 |
|---|---|
| home/livingroom/temperature | ○ |
| home/bedroom/temperature | ○ |
| home/livingroom/humidity | × |
| home/1f/livingroom/temperature | × |
マルチレベルワイルドカード(#)
購読するときだけ、ワイルドカードを利用することができます。(publishは利用不可)
マルチレベルワイルドカードは、そのレベル以下すべてにマッチします。
トピックの末尾にしか置けません。
トピック例
home/#| トピック | マッチ有無 |
|---|---|
| home/livingroom/temperature | ○ |
| home/bedroom/humidity | ○ |
| home | ○ |
パケット構造
MQTT のパケットは、固定ヘッダ/可変ヘッダ/ペイロードの3部構成です。
パケット構造
+----------------------------------------+
| 固定ヘッダ(2バイト〜) | パケット種別 / フラグ / 残りの長さ
+----------------------------------------+
| 可変ヘッダ(種別により有無) | パケットID / トピック名 など
+----------------------------------------+
| ペイロード(種別により有無) | メッセージ本体(任意のバイト列)
+----------------------------------------+パケット種別
主なパケット種別は以下です。
| パケット | 役割 |
|---|---|
| CONNECT / CONNACK | 接続要求と応答 |
| PUBLISH | メッセージの発行 |
| PUBACK / PUBREC / PUBREL / PUBCOMP | 配信確認(QoS 1・2 で使用) |
| SUBSCRIBE / SUBACK | 購読要求と応答 |
| UNSUBSCRIBE / UNSUBACK | 購読解除 |
| PINGREQ / PINGRESP | 生存確認 |
| DISCONNECT | 切断通知 |
MQTTの機能
MQTTの機能について、紹介します。
QoS(Quality of Service)
MQTT は、メッセージの到達保証レベルを3段階から選べます。
回線が不安定な環境を想定した機能です。
QoS 0:At most once(最大1回)
QoS 0は最大1回送信します。
保証イメージ
Publisher --PUBLISH--> BrokerQoS 1:At least once(最低1回)
QoS 1は、最低1回届くまで再送されます。
保証イメージ
Publisher --PUBLISH--> Broker
Publisher <--PUBACK--- BrokerQoS 2:Exactly once(正確に1回)
Qos 2は、正確に1回送信します。
保証イメージ
Publisher --PUBLISH--> Broker
Publisher <--PUBREC--- Broker
Publisher --PUBREL---> Broker
Publisher <--PUBCOMP-- BrokerRetain(保持メッセージ)
通常、Pub/Subでは購読を始めた後に発行されたメッセージしか受け取れません。
センサーが1分に1回しか送らない場合、購読開始直後は最大1分間、値が空のままになります。
Retainフラグを立ててpublishすると、Brokerはそのトピックの最新メッセージを1件だけ保存し、新しく購読したクライアントに即座に配信します。
Will(LWT:Last Will and Testament)
クライアントは、接続時に、WillメッセージをBrokerに預けることができます。
そのクライアントが、正常以外で切断された場合、Brokerが代わりにそのWillメッセージを発行します。
利用例はデバイスの死活監視です。
- 接続時: status/device01にonlineをRetain付きでpublish
- Will登録:status/device01にofflineをRetain付きで設定
デバイスが不意に落ちたときに、Brokerが自動でofflineを流してくれます。
監視側は死活チェックの仕組みを、自前で実装しなくても良いです。
Keep Alive
クライアントは接続時に、Keep Aliveの秒数を指定します。
Keep Aliveの間隔で、送信するものがない場合は、PINGREQを送って生きていることを知らせます。
TCPのコネクションは、片側の電源が突然落ちた場合すぐには切断を検知できません。
Keep Aliveはそれをアプリケーション層で補う仕組みです。
MQTTの使い方(Mosquitto)
MQTTの使い方を紹介します。
本記事では、Mosquittoというブローカーを利用します。
インストール
Mosquittoをインストールします。
コマンドライン
sudo apt install -y mosquitto mosquitto-clientsサービス起動
Mosquittoをサービスとして起動します。
コマンドライン
sudo systemctl start mosquittoPublish(購読)
購読を開始します。
コマンドライン
mosquitto_sub -h localhost -t "home/test"Publish(発行)
別ターミナルからpublishします。
コマンドライン
mosquitto_pub -h localhost -t "home/test" -m "Hello World"セキュリティ
MQTTはデフォルトでは、平文(TCP 1883番ポート)でデータ通信します。
セキュリティ設定を何も設定しなければ、誰でも接続してすべてのトピックを購読できてしまいます。
適切にセキュリティ設定を行って、情報漏洩を防止する必要があります。
認証と暗号化
MQTTでは、認証と暗号化を行うことができます。
| 対策 | 内容 |
|---|---|
| ユーザー認証 | Mosquittoではmosquitto_passwdでパスワードファイルを作成し、password_fileで指定 |
| TLS | 8883番ポートでTLS化する。証明書は Let’s Encrypt や自己署名で用意 |
| ACL | トピック単位でアクセス権を設定し、デバイスが自分のトピックしか触れないようにする |
| クライアント証明書 | デバイス個体ごとに証明書を発行し、相互認証する |
トピック設計
トピック設計は、全デバイスに影響を及ぼすため、後から変えるのが大変です。
トピック設計で注意すべき点を以下に示します。
- 階層を意味のある順に並べる
- ワイルドカードで切り取りたい単位を階層にする
- データ種別を末尾に置く
- デバイス種別などの可変部分を階層に、固定部分を上位にする
Brokerの選択肢
Brokerは、いくつかの種類があります。
本記事では、Mosquittoを利用していますが、その他のツールを紹介します。
| Broker | 特徴 |
|---|---|
| Eclipse Mosquitto | 軽量でシンプルなオープンソースのブローカー |
| EMQX | 大規模分散処理が可能なオープンソースのブローカー |
| HiveMQ | 信頼性が高い企業向けのMQTTプラットフォーム |
| AWS IoT Core | クラウドり利用できるマネージドサービス(SaaS) |
まとめ
MQTTの概要と使い方を紹介しました。
- IoTやM2Mに最適なプロトコル
- Publisher/Subscriber/Brokerの3つで構成される
- 送信側と受信側が互いを知らなくても通信できる
- トピックは/区切りの階層構造で、Publisher/Subscriberが指定する
- セキュリティ設定をすることができる
MQTTは、IoTやM2Mに最適なプロトコルとして設計されています。
自作のIoT機器を作成する際に、採用したいプロトコルの1つです。
