MQTTを使って、IOT通信環境紹介2－MQTTサーバー構築


1、MOTTサーバー（ブローカー）の選び方
　適切なMQTTサーバーを選択するために、QOS、安定性、セキュリティ、およびスケーラビリティなど、いくつかの異なる側面から検討する必要があると思います。
ここでは、以下の技術文書の評価結果を元に、さらに、市場シェア、コミュニティ活動、技術文書の使いやすさ、およびその他の側面と組み合わせて考慮して行こうと思います。
その結果、EMQを選べて、MQTT環境として、構築、テストしようと思います。
https://github.com/mqtt/mqtt.github.io/wiki/server-support

もちろん、EMQ以外、HiveMQとVerneMQなど、非常に優れたMQTTサーバーもあり、自分の業務に適した製品を自由に選択してください。

2、EMQのインストールと設定
■インストール
>sudo yum -y install wget
>sudo yum -y install unzip
>sudo mkdir -p /app/install && sudo cd /app/install
>sudo wget http://emqtt.com/static/brokers/emqttd-centos7-v2.3.11.zip
>sudo unzip emqttd-centos7-v2.3.11.zip && sudo mv emqttd /usr/local

■設定
> vim /etc/profile
> export EMQPATH=/usr/local/emqttd
> export PATH=$EMQPATH/bin:$PATH
> source /etc/profile

■設定検証
>emqttd console
>starting emqttd on node 'emq@127.0.0.1'
>emqttd ctl is starting...[ok]
>emqttd hook is starting...[ok]
>emqttd router is starting...[ok]
>emqttd pubsub is starting...[ok]
>emqttd stats is starting...[ok]
>emqttd metrics is starting...[ok]
>emqttd pooler is starting...[ok]
>emqttd trace is starting...[ok]
>emqttd client manager is starting...[ok]
>emqttd session manager is starting...[ok]
>emqttd session supervisor is starting...[ok]
>emqttd wsclient supervisor is starting...[ok]
>emqttd broker is starting...[ok]
>emqttd alarm is starting...[ok]
>emqttd mod supervisor is starting...[ok]
>emqttd bridge supervisor is starting...[ok]
>emqttd access control is starting...[ok]
>emqttd system monitor is starting...[ok]
>emqttd 2.3.11 is running now
>Eshell V9.0  (abort with ^G)
>(emq@127.0.0.1)1> Load emq_mod_presence module successfully.
>dashboard:http listen on 0.0.0.0:18083 with 4 acceptors.
>mqtt:tcp listen on 127.0.0.1:11883 with 4 acceptors.
>mqtt:tcp listen on 0.0.0.0:1883 with 64 acceptors.
>mqtt:ws listen on 0.0.0.0:8083 with 4 acceptors.
>mqtt:ssl listen on 0.0.0.0:8883 with 16 acceptors.
>mqtt:wss listen on 0.0.0.0:8084 with 4 acceptors.
>mqtt:api listen on 0.0.0.0:8080 with 4 acceptors.

3、EMQの起動
> cd /usr/local/emqttd/bin
> sudo ./emqttd start
> sudo ./emqttd_ctl status
> Node 'node1@172.31.30.158' is started
> emqttd 2.3.11 is running

EMQコンソールにもアクセスできます
http://EMQ Host:18083
<img width="1680" alt="スクリーンショット 2019-02-01 16.02.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/3997f1cf-e882-8be5-4e3f-47068c0efa05.png">

4、EMQクラスタ動作原理
　EMQは、Erlang言語で開発され、MQTT V3.1.1プロトコルを完全にサポートし、クラスタリングと大規模接続をサポートするオープンソースのMQTTメッセージサーバーです。
Erlang / OTP言語プラットフォームのディストリビューションプログラムは、分散のErlang実行システムで構成され、各Erlang実行システムはノードと呼ばれ、ノードはTCPおよびメッセージ通信を介して通信します。
EMQクラスタ図：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304588/9efca909-a129-66bb-b5eb-7e7bad000214.png)

EMQメッセージサーバクラスタは、Erlang / OTP分散設計に基づいていますクラスタリングの仕組みは以下のようになります。
まず、MQTTクライアントがトピックにサブスクライブすると、サブスクリプションが成功した後にトピック所在のクラスタノードは他のノードに通知をブロードキャストします。つまり、このトピックは自分の傘下で管理されることを他のノードに通知することです。
もし後で、MQTTクライアントがメッセージをパブリッシュすようと、リクエスを受けたノードはサブスクリプションを取得し、メッセージのトピックに従って関連するノードにメッセージをルーティングします。
EMQクラスタ内のすべてのノードは、同様なトピックとノードのマッピングテーブルをコピー、更新、維持します。

例えば、次のトピックとノード関係
topic1 -> node1, node2
topic2 -> node3
topic3 -> node2, node4

EMQサーバーの各クラスタノードは、トピックツリーとルーティングテーブルを管理します。
例えば、次のトピックの購読関係
client1	⇨ node1	⇨ t/+/x, t/+/y
client2	⇨ node2	⇨ t/#
client3	⇨ node3	⇨ t/+/x, t/a

以下は、次のトピックツリーとルーティングテーブル（Route Table）を生成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304588/3f7ff0d7-efd3-1509-36b2-9eb50ea01328.png)

たとえば、client1はトピック 't / a'にメッセージを投稿し、そのメッセージはノード間でルーティングされ、ディスパッチされます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/304588/9a9edc36-ec13-3c74-bbdb-5f7da2403e3f.png)

5、試験環境EMQクラスタ構成
2台のサーバーs1.emqtt.ioをデプロイし、クラスタをs2.emqtt.ioにデプロイするとします。
| Node Name         | HOST(FQDN)  | IP           |
| emqx@192.168.0.10 | s1.emqtt.io | 192.168.0.10 |
| emqx@192.168.0.20 | s2.emqtt.io | 192.168.0.20 |

■emqx@s1.emqtt.ioの設定
emqx/etc/emqx.conf:

node.name = emqx@s1.emqtt.io
あるいは
node.name = emqx@192.168.0.10

■emqx@s2.emqtt.ioの設定
emqx/etc/emqx.conf:
node.name = emqx@s2.emqtt.io
あるいは
node.name = emqx@192.168.0.20

■クラスタに参加
2つのノードを起動した後、emqx@s2.emqtt.ioで下記のコマンドを実行します。
$ ./bin/emqx_ctl cluster join emqx@s1.emqtt.io
Join the cluster successfully.
Cluster status: [{running_nodes,['emqx@s1.emqtt.io','emqx@s2.emqtt.io']}]

EMQコンソールでもアクセスで確認できます。
http://EMQ Host1:18083
<img width="1680" alt="スクリーンショット 2019-02-01 16.07.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/4158ea9f-ee1a-1ce1-c353-9e2179ed1274.png">

6、MQTTのクライアントとしてApache NIFIの使用
　メッセージをパブリッシュおよびサブスクライブするためのMQTTのクライアントとしてApache NIFIを使用しており、今後MQTTシステムの性能試験ツールとして使用することができます。 Apache NIFIは非常に強力で、通常はデータパイプラインとビッグデータ処理プラットフォームの窓口として使用されます。 MQTTプロトコルを含むさまざまなネットワーク通信プロトコルに対応できます。

■NIFIのインストール、設定、起動
>sudo yum -y install wget
>sudo yum -y install unzip
>sudo mkdir -p /app/install && sudo cd /app/install
>sudo wget http://ftp.jaist.ac.jp/pub/apache/nifi/1.8.0/nifi-1.8.0-bin.zip
>sudo unzip nifi-1.8.0-bin.zip && sudo mv nifi-1.8.0 /usr/local

> cd /usr/local/nifi-1.8.0/bin
> sudo ./nifi.sh start

> sudo ./nifi.sh status
> Java home: /usr/local/jdk1.8.0_201/
> NiFi home: /usr/local/nifi-1.8.0
> Bootstrap Config File: /usr/local/nifi-1.8.0/conf/bootstrap.conf
> 2019-02-01 15:35:17,572 INFO [main] org.apache.nifi.bootstrap.Command Apache NiFi is currently running, listening to Bootstrap on port 33697, PID=32497

Apache Nifiコンソールにもアクセスできます
http://Apache Nifi Host:8080/nifi/![new-flow.png](https://qiita-image-store.s3.amazonaws.com/0/304588/f60cef20-a8b9-dd92-c223-f5c9e7197f7a.png)

■PublishMQTTプロセッサー設定
メッセージの送信処理フォローを作成して、下記のように、PublishMQTTプロセッサーを設定してください。
<img width="805" alt="スクリーンショット 2019-02-01 15.51.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/5adbe875-1931-bf51-a6c7-f7b82809f574.png">
<img width="807" alt="スクリーンショット 2019-02-01 15.54.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/f763c33e-d6f5-ac0c-a99d-58deb3b1ff24.png">
<img width="803" alt="スクリーンショット 2019-02-01 15.55.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/48f8f6a9-d8b9-6d44-2f2e-26ddcac34359.png">

■ConsumeMQTTプロセッサー設定
メッセージの受信処理フォローを作成して、下記のように、ConsumeMQTTプロセッサーを設定してください。
<img width="807" alt="スクリーンショット 2019-02-01 15.53.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/75875e40-4653-f147-5ff3-79926c6ece8f.png">
<img width="804" alt="スクリーンショット 2019-02-01 15.58.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/3829c998-dd01-0f75-18a0-385dcdca7d3f.png">
<img width="804" alt="スクリーンショット 2019-02-01 15.58.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/f514e201-dfd2-8ce8-7fe2-148d87827972.png">

■NifiのMQTTプロセスーを使用して、メッセージのPUB&SUB確認
<img width="1680" alt="スクリーンショット 2019-02-01 16.17.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/30a6d7e9-7c60-4218-22a1-55a227b29c5d.png">
<img width="1680" alt="スクリーンショット 2019-02-01 16.20.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/dca87416-7fcd-db78-e8bb-ee05d23debe1.png">
<img width="1680" alt="スクリーンショット 2019-02-01 16.21.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/e648e435-8a95-1e72-ca39-747b17a7bf6f.png">

■MQTTLensを使用して、メッセージのSUB確認
下記のサーバー情報を設定して、メッセージをどんどん受信できるはずです。
IP:13.231.151.7
PORT:1883
Topic:nifi
<img width="1680" alt="スクリーンショット 2019-02-01 16.16.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/304588/4a31b6c4-3fc2-d578-beda-460c5c81eabf.png">


7、AWS上のMQTT実現方法について
　現在、AWSは独自のクラウドプラットフォーム上にIOTのソシューションもリリースしており、そのコア機能もMQTTプロトコルを中心に構築されています。 ユーザーは設定ウィザードを通じて、デバイス登録、認証、安全な通信、イベント応答などのAWS IOTサービスを簡単に実装できます。 AWSの独自の柔軟さで理論上無制限の拡張と11個の 9（99.999999999）の高可用性保証とを組み合わせることで、エンタープライズのIOTビジネスプラットフォームを迅速に構築、デプロイできます。今回、時間を探して、AWSのIOTプラットフォームの構築とロードバランサーの実現方法を紹介したいと思います。

参考資料:
https://github.com/mqtt/mqtt.github.io/wiki/server-support
https://nifi.apache.org
http://emqtt.io/docs/v2/index.html
https://kebingzao.com/2018/11/19/vernemq-docker-cluster/
https://medium.com/@emqtt/deploying-emq-with-elastic-load-balancer-on-aws-21402322f711