MENU
やすひら
やすひらと申します。
長靴を履いたタヌキ(ITエンジニア)です。
モノ作りの楽しさを発信中。
X(旧Twitter)のフォローもお願いします。

[初心者向け] MQTTとは? | 概要と使い方を解説

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が設計したプロトコルです。

項目HTTPMQTT
通信モデル要求 → 応答発行 → 購読
接続リクエストごとに確立常時接続を維持
送信の起点クライアントのみBroker経由でPublishが送信する
宛先の指定URLトピック
最小ヘッダサイズ
相手の数基本1対11対多、多対多

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 ]
                                                       Subscriber
Brokerを経由して、メッセージを送受信します。
クライアント同士が直接つながることはありません。
Brokerは、受け取ったメッセージを、そのトピックを購読しているクライアント全員に配信します。

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

単独ですべてのトピックを購読することもできますが、$SYS/のような$始まりのトピックにはマッチしません。

パケット構造

MQTT のパケットは、固定ヘッダ/可変ヘッダ/ペイロードの3部構成です。

パケット構造

+----------------------------------------+
| 固定ヘッダ(2バイト〜)          |  パケット種別 / フラグ / 残りの長さ
+----------------------------------------+
| 可変ヘッダ(種別により有無)   |  パケットID / トピック名 など
+----------------------------------------+
| ペイロード(種別により有無)   |  メッセージ本体(任意のバイト列)
+----------------------------------------+

ペイロードの中身はプロトコルとして規定されていません。
JSONやCSV、生のバイナリを設定でき、どんなデータ規定も利用することができます。

パケット種別

主なパケット種別は以下です。

パケット役割
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--> Broker

送りっぱなしです。確認応答がないため、届かなくても再送されません。
最も軽量でデータ送信ができます。
用途:1秒ごとに送る温度センサーの値など、1回落ちても次が来るので困らないデータ。

QoS 1:At least once(最低1回)

QoS 1は、最低1回届くまで再送されます。

保証イメージ

Publisher --PUBLISH--> Broker
Publisher <--PUBACK--- Broker

PUBACK が返るまで再送します。
確実に届きますが、PUBACK が失われた場合に再送されるため、同じメッセージが複数回届く可能性があります。

用途:多くのケースで現実的な選択肢。受信側で重複を許容できる設計にしておくのがポイントです。

QoS 2:Exactly once(正確に1回)

Qos 2は、正確に1回送信します。

保証イメージ

Publisher --PUBLISH--> Broker
Publisher <--PUBREC--- Broker
Publisher --PUBREL---> Broker
Publisher <--PUBCOMP-- Broker

4回のやり取りで重複を排除します。
確実ですが、往復が増えるぶん遅く、Broker 側の状態管理コストも高くなります。

用途:課金処理や、二重実行が許されないコマンド送信など。

PublisherとSubscriberの指定によって、実際のQoSは低いほうになります。
PublisherがQoS 2で送っても、SubscriberがQoS 0で購読している場合は、QoS 0で配信されます。

Retain(保持メッセージ)

通常、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がBroker、mosquitto-clientsが動作確認に使うmosquitto_pub/mosquitto_subというコマンドです。

サービス起動

Mosquittoをサービスとして起動します。

コマンドライン

sudo systemctl start mosquitto

Mosquitto、デフォルトではローカルホストからの接続のみを受け付けます。

他のマシンから接続する場合は/etc/mosquitto/conf.d/にlistenerと認証の設定を追加する必要があります。

Publish(購読)

購読を開始します。

コマンドライン

mosquitto_sub -h localhost -t "home/test"

接続を維持したまま待ち受け状態になります。

Publish(発行)

別ターミナルからpublishします。

コマンドライン

mosquitto_pub -h localhost -t "home/test" -m "Hello World"

購読側のターミナルに”Hello World”が表示されたら成功です。

セキュリティ

MQTTはデフォルトでは、平文(TCP 1883番ポート)でデータ通信します。
セキュリティ設定を何も設定しなければ、誰でも接続してすべてのトピックを購読できてしまいます。
適切にセキュリティ設定を行って、情報漏洩を防止する必要があります。

認証と暗号化

MQTTでは、認証と暗号化を行うことができます。

対策内容
ユーザー認証Mosquittoではmosquitto_passwdでパスワードファイルを作成し、password_fileで指定
TLS8883番ポートでTLS化する。証明書は Let’s Encrypt や自己署名で用意
ACLトピック単位でアクセス権を設定し、デバイスが自分のトピックしか触れないようにする
クライアント証明書デバイス個体ごとに証明書を発行し、相互認証する

トピック設計

トピック設計は、全デバイスに影響を及ぼすため、後から変えるのが大変です。
トピック設計で注意すべき点を以下に示します。

  • 階層を意味のある順に並べる
  • ワイルドカードで切り取りたい単位を階層にする
  • データ種別を末尾に置く
  • デバイス種別などの可変部分を階層に、固定部分を上位にする

Brokerの選択肢

Brokerは、いくつかの種類があります。
本記事では、Mosquittoを利用していますが、その他のツールを紹介します。

Broker特徴
Eclipse Mosquitto軽量でシンプルなオープンソースのブローカー
EMQX大規模分散処理が可能なオープンソースのブローカー
HiveMQ信頼性が高い企業向けのMQTTプラットフォーム
AWS IoT Coreクラウドり利用できるマネージドサービス(SaaS)

個人開発や自宅のIoTであれば、手軽に利用しやすいMosquittoを採用するのが良いと思います。

まとめ

MQTTの概要と使い方を紹介しました。

MQTTは
  • IoTやM2Mに最適なプロトコル
  • Publisher/Subscriber/Brokerの3つで構成される
  • 送信側と受信側が互いを知らなくても通信できる
  • トピックは/区切りの階層構造で、Publisher/Subscriberが指定する
  • セキュリティ設定をすることができる

MQTTは、IoTやM2Mに最適なプロトコルとして設計されています。
自作のIoT機器を作成する際に、採用したいプロトコルの1つです。

  • URLをコピーしました!
目次