2020.07.01 · 技術と道具

Mosquittoの負荷分散クラスタをNginxで構成する

IoTの導入にあたりMQTTを使うケースは多いと思います。導入機器が増えてくると、MQTTへのトラフィックが増えてくるので、ブローカーの負荷分散をしたいとか、ブローカーが落ちてメッセージを処理できない事態を避けたいという要件が出てきます。

ブローカーとしてAWSなどのクラウドで提供されているIoTサービスを活用するのであれば問題ありませんが、自分で立てたサーバにMosquittoなどを導入してブローカーとして使用している場合です。

Mosquittoにはブリッジという機能があり、自分のところにきたメッセージを、そのまま別のブローカーに連携することはできます。ただ、これは負荷分散のための機能ではありません。
他に目につくような機能もないし…。もともと、MosquittoはMQTTのリファレンス実装として開発されているものであり、MQTTの仕様にある機能についてはスピーディに実装されますが、そうでないものについては実装されません。負荷分散の機能は、MQTTの仕様にないので、実装されていないのは当たり前ともいえます。

Nginxを使って負荷分散クラスタを構成する

今回構成するのは負荷分散クラスタです。複数のブローカーを起動させ、平常時は負荷分散でメッセージを処理します。そして、あるブローカーが落ちてしまった場合は、残りのブローカーでメッセージを落とさず処理を継続します。

まず、複数のマシンを準備して、それぞれにMosquittoをインストールしてブローカーを常時起動させます。ここでは、192.168.10.253と192.168.10.254にそれぞれブローカーを起動させ、ポート1883番で待ち受けさせます。
ブローカーにログインなどの設定をしている場合は、どちらのブローカーにも同じ設定をします。

Nginxの設定は、まず/etc/nginx/modules-available/mqtt.confを作成し、下記のようにします。

NGINX
stream {
  upstream mqtt {
    server 192.168.10.254:1883;
    server 192.168.10.253:1883;
  }

  server {
    listen 1884;
    proxy_pass mqtt;
  }
}

streamの設定は、Nginxの設定上、httpと同じレベルにしなければなりません。Ubuntu 18.04 LTSにaptで導入したNginxでは、nginx.confにおいてhttpと同じレベルで/etc/nginx/modules-enabled/*.confのインクルードが設定されているので、この場所にしました。(あまり正しい場所ではないかもしれません。)

最後に、シンボリックリンクを作成して、有効にしてからNginxをreloadします。

BASH
cd /etc/nginx/modules-enabled
ln -s ../modules-available/mqtt.conf
systemctl reload nginx

これだけでOKです。

ここまでの設定では負荷分散はデフォルトのラウンドロビンで行われます。
また、片方のブローカーが落ちた場合は、もう片側のブローカーですべての処理が行われ、復帰すると再びラウンドロビンで処理されるようになります。

2020/07/01 19:47
← Jetson nanoにTensorFlow 1.15とKe…
EPSON Endeavor ST190Eを中古で導入 →
井上 研一
経済産業省推進資格ITコーディネータとして中小企業のDX・AI活用の現場で伴走支援を行う。「ITCプロセスガイドライン4.0」および「中小企業向けAI活用ガイド」執筆メンバー。著書・講演多数。ITエンジニアとして25年以上の実務経験。AI導入の実務に10年以上携わる。自ら開発したAIサービス「Gen2Go」が北九州発!新商品創出事業の認定を受ける。2026年4月より北九州市立大学大学院マネジメント研究科の学生としての顔も持つ。

本サイトおよびブログに掲載している内容は、特に明記のない限り、井上研一個人の見解に基づくものです。所属・関与する組織、団体、企業、研究会等の公式見解を示すものではありません。