IoTの世界でサーバーエンジニアに存在価値はあるんでしょうか?
とりあえず MQTTブローカーを立ち上げましょう。
IoT(Internet of Things)という言葉が世に出てから大分経ちますが、私はこれに関わったことがございません。
インターネットにある情報を見る限り、様々な物理的な機器をインターネットで繋ぐ(M2M:Machine to Machine)から始まり、今良く目にするのは機器のセンサーデータなどをパブリッククラウドに集め分析に回すというものですね。
私はラズベリーパイを買った際に、センサーを繋いでってのをやってみたかったんですがまだ手を着けていません。
AWSの LocalStackを少しいじるようになって、AWSの IoT Core ってサービスは何をしてるのかな?サーバーエンジニアの出番ってあるのかな?と思い、今回はこのネタで一つ書くことにしました。
パブリッククラウドにおいて、AWSと Azureにはそれぞれ IoT機器(この呼び名が正しいのか分かりませんが)との通信を行うサービスが存在しています。
AWS | IoT Core |
Azure | IoT Hub |
両方とも、クラウド側に IoT機器からデータを受け取る、クラウドから IoT機器の操作を行う、という双方向の通信をするもののようです。
ただ IoT機器がこれらのサービスに独自対応しているのではなく、既存の汎用的な通信プロトコルを使って通信するようにしてあり、そのおかげで広く多くの機器がこれを利用できるようです。
私の想像図はこんな感じです。
機器の方はハードウェアですから、その仕様に合わせて AWSも Azureもサービス展開している感じで、[機器→クラウドのIoTサービス]に使われるプロトコルはいくつかあるようですが、MQTTという昔 IBMが策定したものが一般的なようですね。
実際に機器を扱ったことが無いので、どこまで汎用的になっているか分かりませんけど、パブリッククラウド側がそれに応じているところからして、きっと汎用的なのでしょう。
MQTTはシンプルなプロトコルで、データのオーバヘッドが少なく、ゆえに少電力であるということでした。(なるほど)
さて、ここでは機器とクラウドの間の関係において、サーバーエンジニアの出番があるのかを考えています。
パブリッククラウドのサービスでは直接機器を1つずつ登録するようになっています。
これは有線で繋げない機器からのデータ転送を携帯電話会社の無線を通じて直接インターネットを経由させることを目的にさせているように思います。
もし機器が社内にあって(例えば工場とか)、有線か Wifiなど何かしらの通信手段が取り得るなら、社内のサーバーにデータを溜め込むんじゃないかって思います。
最終的なデータ分析はクラウド上でやるかも知れませんけれども、それは IoTのデータ集めとは別な話しでしょう。
というわけで、ここでは MQTTというプロトコルを使って機器からデータを集める所だけですが、作ってみようと思います。
これにはメッセージブローカーと呼ばれるサーバーを使います。
ここで使うのはこれ。
mosquitto
Eclipseなんですね。モスキートって読んでいいのかな?
このメッセージブローカーと呼ばれるサーバーですが、一般的にはこのような関係のなるようです。
mosquittoはキューサーバーではないと聞きましたが、キューの考えそのまんまです。
これを上の図にあてはめるとこんな感じでしょうか。
このうちここだけですが、作ってみます。
環境は以下の通り。
まず mosquittoのインストールから。
Ubuntu 22.04 には snap版がありましたので、それを入れます。
subro@UbuntuServer2204-1:~$ sudo snap install mosquitto
mosquitto 2.0.15 from Mosquitto Team (mosquitto✓) installed
2023年3月7日時点で 2.0.15が入りました。
インストールすると即立ち上がって 1883/tcpで待ち受けているんですが、バインドされているのが localhost(127.0.0.1)だけですので、これだと外部から接続できません。
snap版の場合、設定ファイルの雛形として
/var/snap/mosquitto/common/mosquitto_example.conf
がありますので、これをコピーして、
/var/snap/mosquitto/common/mosquitto.conf
というファイルを作ります。
作ったファイルの最後に以下の 2行を追加して下さい。
(2行目は認証を必要とさせない設定です)
listener 1883 0.0.0.0
allow_anonymous true
設定ファイルができたら、mosquittoのサービスを再起動します。
subro@UbuntuServer2204-1:~$ sudo systemctl restart snap.mosquitto.mosquitto.service
subro@UbuntuServer2204-1:~$ ss -l4
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.53%lo:domain 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.53%lo:domain 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:ssh 0.0.0.0:*
tcp LISTEN 0 100 0.0.0.0:1883 0.0.0.0:*
0.0.0.0(IP ALL)で待ちうけるようになりました。
これで mosquittoサーバー(メッセージブローカー)の準備は OKでしょう。
次に サブスクライバーを準備します。
これは mosquittoをインストールした際に、mosquitto_sub というコマンドが一緒にインストールされていますので、それを実行します。
-t は「トピック」を指すものですが、キューイングシステムでのキュー名と似た感じですかね。
あとでパブリッシャーでも同じトピックを指定して、メッセージを送信します。
subro@UbuntuServer2204-1:~$ mosquitto_sub -h localhost -t topic
これでメッセージが来るのをずっと待っていますので、そのままにしておきましょう。
最後はパブリッシャーとなるラズベリーパイの Node-REDのフローとなります。
こんなのを作りました。
[タイムスタンプ]が injectノード、[topic]が mqtt outノードです。
[タイムスタンプ]は変更一切なしで、[topic]の方の変更点は以下の通り。
[サーバ]は任意の名前、[トピック]は上で決めた「topic」にします。
右の鉛筆ボタンを押した所に mosquittoサーバーの情報を入れます。
[サーバ]に mosquittoサーバーのIPかマシン名を、
[プロトコル]は[MQTT V5]にしました。(今はこれだそうなので)
設定ができたら、赤枠をクリックすると 1回実行されます。
これで mosquittoにデータが送られたはずです。
待たせていたサブスクライバー(mosquitto_subコマンド)を見てみると…
subro@UbuntuServer2204-1:~$ mosquitto_sub -h localhost -t topic
1678165021962
出ましたね。
この数字は何かというと、Node-REDの injectionノードで、日時をメッセージとして mqtt outノードに渡しているので、それを数値化したものが出てるのでしょうね。
ちょっと Node-REDをいじってみたらこんな風になりましたので、良さげと思います。
subro@UbuntuServer2204-1:~$ mosquitto_sub -h localhost -t topic
1678165021962
Hello IoT!
という訳で、IoT機器からのデータ転送とそれを受け取る仕組みのお勉強として、MQTTでのデータ転送をやってみました。
私は以前「RabbitMQでメッセージを受け渡し」で、こちらはキューイングのあるメッセージブローカーの RabbitMQ というのを扱っています。
対して mosquittoはキューイングの機能がないようなので、パブリッシャーがデータを送った時にサブスクライバーがいないとデータが捨てられてしまうのかも知れません。
パブリッククラウドのサービスは何を使っているのか分かりませんが、多分キューイングの機能はあるのだと思います。
RabbitMQのプロトコルは AMQPというものですが、プラグインを追加することによって MQTTが使えるとのこと。
もし社内にこのような仕組みを作るのなら、RabbitMQも候補に入れても良さそうです。
日本語本は多分ゼロ!
IoTで遊ぶなら