# ロードバランサーの設定

ロードバランサー（LB）は複数のネットワークコンポーネント間で負荷を分散し、リソースの使用を最適化することで、過負荷によるシステム障害を回避します。LBはEMQXの必須コンポーネントではありませんが、以下のような明確なシステム上の利点をもたらします。

- EMQXの負荷を分散し、単一ノードの過負荷を回避する；
- クライアントの設定を簡素化し、クライアントはLBにのみ接続すればよく、クラスター内のスケーリングを意識する必要がない；
- TLS/SSL終端によりEMQXクラスターの負荷を軽減する；
- クラスターの前面にLBを配置することで不要なトラフィックを遮断し、EMQXクラスターを悪意のある攻撃から保護してセキュリティを向上させる。

本節では、EMQXにおけるLBの設定方法について解説します。

## デプロイメントアーキテクチャ

本節では、3つの異なるロードバランサーのデプロイメントアーキテクチャを紹介します。

### TCPロードバランサー

LBを設定したEMQXクラスターでは、LBが受信したTCPトラフィックを処理し、受け取ったMQTT接続要求やメッセージを異なるEMQXノードに振り分けます。典型的なデプロイメントアーキテクチャは以下の通りです。

<img src="./assets/lb_2.png" alt="TLS終端" style="zoom:45%;" />

### TLS終端とロードバランサー

SSL/TLSが有効な場合は、LBでSSL/TLS接続を終端することを推奨します。つまり、クライアントとLB間はSSL/TLSで保護し、LBとEMQXノード間はTCP接続を使用することで、EMQXクラスターのパフォーマンスを最大化します。アーキテクチャは以下の通りです。

<img src="./assets/lb_3.png" alt="image" style="zoom:50%;" />

### ハイブリッドデプロイメント

クラウドサービスプロバイダーのLBを接続および負荷分散層として利用したいが、TLS終端に対応していない、またはプロキシプロトコルなどのTLS機能が不足している場合は、ハイブリッドデプロイメントを選択できます。具体的には、EMQXの前にHAProxyやNGINXを配置してSSL/TLS接続を終端します。

EMQXで直接TLS接続を処理するよりも、この方法のほうがより高いパフォーマンス効果が得られます。デプロイメントアーキテクチャは以下の通りです。

<img src="./assets/lb_6.png" alt="EMQXロードバランシングハイブリッドデプロイメント" style="zoom:80%;" />

負荷分散デプロイメントクラスターに加えて、DNSラウンドロビンを用いてEMQXクラスターに直接接続する方法もあります。これはすべてのノードをDNSラウンドロビンリストに追加し、デバイスがドメイン名またはIPアドレスリスト経由でクラスターにアクセスする方法です。ただし、DNSラウンドロビンは本番環境での利用は一般的に推奨されません。

## 実IPおよびTLS証明書情報の取得

LBをデプロイした後、EMQXは通常、クライアントの実際の送信元IPやTLS証明書情報を取得する必要があります。そのためには、LBで[プロキシプロトコル](https://www.haproxy.com/blog/haproxy/proxy-protocol)の設定を有効にするか、実IPを取得するための関連設定を有効にする必要があります。

LBでプロキシプロトコルを有効にした場合、EMQXの該当リスナーでも`proxy_protocol`設定を有効にする必要があります。例えば、TCP 1883リスナーの場合、設定ファイルに以下を追加します。

```bash
listeners.tcp.default {
  bind = "0.0.0.0:1883"
  max_connections = 1024000

  proxy_protocol = true
}
```

LBでのプロキシプロトコル有効化方法については、各LBのドキュメントを参照してください。プロキシプロトコルをサポートしないLB製品でも、バックエンドサービスが実際のクライアントIPを取得できる場合があります。ご利用のLBやクラウドサービスプロバイダーの要件に応じて適切に設定してください。

### クライアントTLS証明書情報

プロキシプロトコルv2は、ロードバランサーからEMQXのTCPリスナーへクライアントTLS証明書の一部情報（Common Name（CN）やSubjectなど）を転送できます。ただし、証明書のSubject Alternative Names（SANs）は転送されません。

`cert_san.*`の値からクライアント属性を初期化するには、TLS接続がEMQXで終端され、クライアントがEMQXのTLSリスナーに証明書を提示する必要があります。ロードバランサーでTLSを終端すると、SAN値はEMQXに渡されません。ロードバランサーがTLS接続を終端せずにEMQXに転送する場合、クライアント証明書はEMQXに提示され、EMQXはSANを抽出できます。設定の詳細は[証明書のSubject Alternative Namesからクライアント属性を初期化する](../../develop/client-attributes/client-attributes.md#initialize-client-attributes-from-certificate-subject-alternative-names)を参照してください。

## LB製品の選定

現在、多くのLB製品が存在し、オープンソース版や商用版、さらにパブリッククラウドプロバイダーのロードバランシングサービスも利用可能です。

パブリッククラウド向けLB製品：

| クラウドプロバイダー                      | SSL終端対応 | プロキシプロトコル対応 | LB製品                                                    |
| ----------------------------------------- | ----------- | ---------------------- | --------------------------------------------------------- |
| [AWS](https://aws.amazon.com)             | 対応        | 対応                   | <https://aws.amazon.com/elasticloadbalancing/?nc1=h_ls>   |
| [Azure](https://azure.microsoft.com)      | 不明        | 不明                   | <https://azure.microsoft.com/en-us/products/load-balancer/> |
| [Google Cloud](https://cloud.google.com/) | 対応        | 対応                   | <https://cloud.google.com/load-balancing>                 |

プライベートクラウド向けLB製品：

| オープンソースLB                      | SSL終端対応 | プロキシプロトコル対応 | ドキュメント/URL                                         |
| ------------------------------------ | ----------- | ---------------------- | ------------------------------------------------------- |
| [HAProxy](https://www.haproxy.org)  | 対応        | 対応                   | <https://www.haproxy.com/solutions/load-balancing.html> |
| [NGINX](https://www.nginx.com)       | 対応        | 対応                   | <https://www.nginx.com/solutions/load-balancing/>       |

以降の2ページでは、プライベートにデプロイしたLBサーバーを例に、EMQXクラスターの設定およびロードバランシング方法を紹介します。

- [NGINXによるEMQXクラスターのロードバランス](./lb-nginx.md)
- [HAProxyによるEMQXクラスターのロードバランス](./lb-haproxy.md)
