# EMQX CloudにおけるMQTTクライアント開発のベストプラクティス

Message Queuing Telemetry Transport（MQTT）は、IoTアプリケーションで広く採用されている柔軟かつ軽量なパブリッシュ・サブスクライブプロトコルです。しかし、その柔軟性と豊富な機能セットのために、クライアント側での不適切な設定や実装はパフォーマンスの問題を引き起こし、システム全体の安定性に影響を与える可能性があります。

本ページでは、EMQX Cloudに接続し通信するMQTTクライアントを開発する際のベストプラクティスを紹介します。これらのガイドラインに従うことで、EMQXの機能を最適に活用しつつ、スケール時の安定性、パフォーマンス、セキュリティを維持できます。

取り扱うトピックは、接続管理、トピック階層設計、QoS設定、メッセージパブリッシュ戦略、共有サブスクライブや保持メッセージ、イベント駆動型データ統合などEMQX固有の機能の効果的な活用方法です。

## 接続管理

MQTTクライアントは、データフローの途切れを防ぎ、断続的なネットワーク状況に柔軟に対応し、クライアントおよびブローカー双方のリソース使用を最小化するために、接続を効率的に管理する必要があります。

本セクションでは、EMQX Cloudとやり取りする際のクライアント接続の確立、維持、復旧に関する基本的な実践方法を解説します。

### 安定した接続の確立と維持

#### クライアントIDの設定

各MQTTクライアントは、ブローカーとのセッションを確立するために一意の識別子を使用する必要があります。適切なクライアントID設計は、接続の競合回避やクライアントのライフサイクル管理を容易にします。

- クライアントIDは一意にし、IDの競合を避けること。
- デバイスのシリアル番号やUUIDを一意識別子として利用することを検討する。
- 大規模展開の場合は、`{product_type}-{region}-{device_id}`のような構造化された命名規則を用いる。
- クライアントIDは64文字以内に抑え、不要なネットワークやメモリのオーバーヘッドを避ける。
- 使用可能な文字は英数字、ハイフン`-`、アンダースコア`_`のみに限定する。
- パスワードやシークレット、トークンをクライアントIDに埋め込まない。ログや監視システムに表示される可能性があるため。
- 永続セッションを有効にする場合（`Clean Session = False`）、クライアントIDは固定する必要がある。そうしないと前回のセッション状態が正しく復元されない。

#### キープアライブ間隔

キープアライブ間隔は、クライアントが接続を維持するためにブローカーと通信する頻度を定義します。適切な値を選択することで、切断検出のタイムリーさと不要なネットワーク負荷のバランスを取れます。

- クライアントのネットワーク環境に応じて、通常30秒から250秒の範囲でキープアライブ間隔を設定する。
- 不安定またはモバイルネットワークでは、60～120秒程度の短めの間隔を設定し、接続喪失を速やかに検出する。
- 安定した高信頼ネットワークでは、180～250秒の長めの間隔でネットワークトラフィックを削減可能。
- クライアントはキープアライブ間隔が切れる前にハートビート（PINGREQ）パケットを送信し、ブローカー側の切断を回避する。
- NATゲートウェイ環境では、30秒以内の間隔を維持し、中間ネットワーク機器による静かな接続切断を防ぐ。
- 低消費電力デバイスでは、デバイスのスリープ・ウェイクアップ動作と合わせて設計し、250秒程度まで間隔を緩和可能。
- 頻繁にパブリッシュするデバイスは、ビジネスメッセージ自体が接続維持に寄与するため、180～250秒の長めのハートビート間隔も許容される。
- ブローカー側のタイムアウトは通常、`1.5 × キープアライブ`で評価される。

#### セッション管理

MQTTのセッションは、ブローカーがクライアントの状態（サブスクリプションや未配信メッセージなど）を保持するかどうかを決定します。適切なセッションタイプの選択は、メッセージ配信の信頼性とリソース使用に影響します。

- メッセージ配信の継続性やサブスクリプションの復元が必要な場合は、永続セッション（`Clean Session = False`）を有効にする。
- リアルタイムデータのみが必要なクライアントは、一時セッション（`Clean Session = True`）を使用し、ブローカーのリソース使用を削減する。
- 永続セッションには適切なセッション有効期限を設定し、ブローカーのメモリやディスクリソースの長期消費を防ぐ。
- 大規模デバイス展開では、永続セッションの使用は必要な場合に限定し、慎重に運用する。

### 切断と復旧の対応

現実のネットワーク環境では断続的な接続切断が一般的です。自動再接続機構や指数バックオフ戦略を実装することで、接続復旧の成功率を効果的に向上できます。

#### 自動再接続機構

切断後の自動再接続はサービス継続性を確保し、手動介入を減らします。

- 予期しない切断後に接続を自動復旧する機能を有効にする。
- 接続状態を監視し、切断を速やかに検知して対応する。
- 初回の再接続間隔は1秒に設定する。
- 再接続成功後は必要なサブスクリプションやクライアント状態を自動復元する。

#### 指数バックオフ戦略

指数バックオフは、複数クライアントが同時に再接続を試みる際の接続集中を防止します。

- 再接続失敗ごとにリトライ間隔を倍増させ、接続集中を回避する。
- 最大バックオフ間隔（例：120秒）を設定し、リトライ遅延を上限で制御する。
- ネットワーク復旧（インターフェース状態変化や信号回復）を検知したら即座にリセットして再試行する。
- 再接続間隔に10%～30%のランダムジッターを加え、多数クライアントの同時再接続を防ぐ。

### 接続タイムアウトの推奨設定

- 接続確立のタイムアウトは10～30秒に設定する。無限待機はネットワーク完全不通時にクライアント状態機械をブロックするため避ける。
- タイムアウト後は速やかに再接続フローに入り、エラー原因と経過時間をログに記録する。

## トピックサブスクリプションの管理と最適化

トピックサブスクリプションはMQTT通信の中核であり、クライアントが関連するメッセージを受信するために不可欠です。しかし、過剰なフィルターや非効率な階層設計はブローカー負荷の増大、メッセージルーティング遅延、クライアント側の不要な処理増加を招きます。

本セクションでは、EMQX Cloud接続時のトピックサブスクリプション管理と最適化のベストプラクティスを示します。

### QoSレベル別サブスクリプション制限

特に高いQoSレベルで多数のトピックをサブスクライブすると、クライアント・ブローカー双方の処理負荷が増大します。最適なパフォーマンス維持のため、以下の推奨上限を設けています。

| QoSレベル | 配信保証       | 推奨最大サブスクリプション数 |
| --------- | -------------- | ----------------------------- |
| QoS 0     | 最多1回        | 100                           |
| QoS 1     | 少なくとも1回  | 50                            |
| QoS 2     | 正確に1回      | 25                            |

> これらは一般的な利用パターンに基づくベストプラクティスの指標です。厳密な制限ではありませんが、超過すると特にリソース制約環境で性能低下を招く可能性があります。

### ワイルドカードトピックのサブスクライブ

ワイルドカードフィルターは、単一のサブスクリプションで複数トピックをまとめて受信でき、設定を簡素化しサブスクリプション数を削減します。

- **単一レベルワイルドカード（`+`）**：1階層のみマッチ。
  例：`sensor/+/temperature`は`sensor/room1/temperature`や`sensor/room2/temperature`にマッチ。
- **複数レベルワイルドカード（`#`）**：現在階層以下の1階層以上にマッチ。
  例：`sensor/#`は`sensor/room1/temperature`、`sensor/room2/humidity`、`sensor/room3/status/battery`にマッチ。

**ベストプラクティス：**

管理の複雑さを減らすため、適用可能な場合はワイルドカードサブスクライブを活用してください。ただし、ルートレベルでの`#`など過度に広範囲なフィルターは、クライアントが大量の無関係なメッセージを受信し、処理負荷とメモリ使用量が増加するため避けるべきです。パブリッシュ時にはワイルドカード（`#`や`+`）を使用しないでください。

### トピック階層設計

整理されたトピック設計は、サブスクリプション管理、アクセス制御、MQTT展開のスケーラビリティ向上に寄与します。明確かつ一貫性のあるトピック設計はクライアント・ブローカー双方のパフォーマンスを改善します。

#### トピック構造のベストプラクティス

- **統一されたトピック形式を使用する**  
  例：  
  ```
  {product_type}/{region}/{device_id}/{data_type}
  ```

- **トピック階層の深さを制限する**  
  通常は5階層以内に抑え、複雑な場合でも7階層を超えないようにする。深すぎる階層はルーティングの複雑化とパフォーマンス低下を招く。

- **先頭ワイルドカードを避ける**  
  `#/+`や`+/#`のようなパターンは曖昧さを生み、ブローカー側のトピックマッチング計算量を増加させるため使用しない。

- **メッセージ種別ごとにカテゴリを分ける**  
  コマンド用とデータ用で異なるプレフィックスを使う。例：  
  ```
  cmds/device001     # デバイスへのコマンド  
  data/device001     # デバイスからのデータ
  ```

- **トピック長を制御する**  
  ネットワークオーバーヘッドやメモリ消費を抑えるため、合計トピック長は100文字以内にする。

- **システムトピックを分離する**  
  システムレベルのトピックはビジネストピックから分け、適宜`$`プレフィックスを使用する。

- **ACL制御を考慮した設計**  
  将来的な権限管理、テナント分離、運用クエリ要件を見据えた階層設計を行う。

## QoSレベルとパフォーマンス

MQTTプロトコルは、クライアントとブローカー間のメッセージ配信信頼性を定義する3つのQoSレベルをサポートしています。適切なQoSレベルの選択は、ネットワークトラフィック、処理負荷、システム全体のパフォーマンスに直接影響します。

本セクションでは各QoSレベルの概要、パフォーマンス推奨、およびEMQX利用時の最適化戦略を解説します。

### QoSレベルの説明

各QoSレベルは配信信頼性と通信オーバーヘッドのトレードオフを表します。

| QoSレベル | 配信保証       | 代表的なユースケース                         |
| --------- | -------------- | -------------------------------------------- |
| QoS 0     | 最多1回        | 重要度の低いテレメトリ、周期的センサーデータ |
| QoS 1     | 少なくとも1回  | 重複許容可能な重要データ                     |
| QoS 2     | 正確に1回      | コマンドやトランザクションなど重要メッセージ |

> 高いQoSレベルほど信頼性は向上しますが、プロトコルオーバーヘッドや処理レイテンシが増加します。QoS 2は4段階のハンドシェイクが必要で最もコストが高いため、慎重に使用してください。

### クライアント側パフォーマンスガイドライン

MQTTクライアントのメッセージスループットは選択したQoSレベル、内部スケジューリングロジック、デバイス性能に左右されます。以下はクライアント単位の推奨スループット範囲です。

| QoSレベル | 推奨最大メッセージ数/秒（クライアント単位） |
| --------- | -------------------------------------------- |
| QoS 0     | 1,000                                        |
| QoS 1     | 300                                          |
| QoS 2     | 150                                          |

> これらは一般的なMQTTクライアントの挙動に基づく推奨値です。実際の限界はハードウェア、実装効率、メッセージサイズに依存します。

過剰なサブスクリプション数やメッセージバーストはクライアント側のスケジューリング遅延や処理効率低下を招くため避けてください。

### 最適化戦略

信頼性とパフォーマンスのバランスを取るため、以下のベストプラクティスを検討してください。

- ビジネス要件が許す場合は、**低いQoSレベルを優先的に使用**する。例：ストリーミングテレメトリにはQoS 0。
- **共有サブスクライブ**を利用し、複数のバックエンドコンシューマー間でメッセージ負荷を分散する。
- **バッチパブリッシュ**を実装し、メッセージごとのオーバーヘッドとリソース消費を削減する。
- 大きなペイロードには**メッセージ圧縮**を適用し、制約のあるネットワークでの伝送効率を向上させる。
- QoSはビジネスニーズに合わせて選択する。センサーデータや頻繁に変化する状態はQoS 0、アラートや制御コマンドはQoS 1、トランザクションや課金処理など厳密な重複排除が必要な場合のみQoS 2を使用。

## メッセージパブリッシュ戦略

効率的なメッセージパブリッシュは、帯域使用量の削減、処理負荷の軽減、エンドツーエンドの配信性能向上に寄与します。本セクションでは、EMQXブローカーへのパブリッシュ時におけるメッセージサイズ、頻度、構造、内容の管理に関する推奨事項を示します。

### パブリッシュのベストプラクティス

適切なメッセージ管理により、システム負荷を軽減しクライアント・ブローカー双方のスループットを向上させます。

#### メッセージサイズの制御

大きすぎるまたは非効率なメッセージは配信遅延やメモリ使用増加を招きます。

- 個別メッセージは可能な限り128 KB以下に抑える。MQTTには小さなメッセージ（1 KB程度）が適している。
- 極端な場合でも1 MBを超える単一メッセージは避ける。
- 大きなペイロードはチャンク分割送信や外部参照（ファイルURLなど）を検討する。
- 非常に小さいメッセージの大量送信は避け、適宜バッチ化する。

#### パブリッシュ頻度の管理

データ送信頻度の制御は、システム応答性とリソース効率のバランスを取るために重要です。

- 過度に高頻度のパブリッシュはクライアントやブローカーのリソース枯渇を招くため避ける。
- 変化検知トリガー型のパブリッシュを活用し、データ変化時のみ送信する。
- スロットリングや集約機構を実装し、パブリッシュ頻度を抑制しデータフローを平滑化する。
- バーストトラフィックに対応するため、バックプレッシャー、レートリミット、バッファ保護戦略を設計する。

#### メッセージ重要度の優先付け

適切な優先度とQoS設定により、重要データの信頼性を確保しつつ、重要度の低いデータのオーバーヘッドを最小化します。

- コマンドやアラートなど重要データには高いQoSレベルを使用し、確実な配信を保証する。
- 重要度の低いテレメトリや頻繁な更新には低いQoSやバッチパブリッシュを利用する。

### メッセージフォーマットとペイロード最適化

効率的なペイロード設計は処理速度を向上させ、帯域使用量を削減し、下流の解析や処理を簡素化します。

#### 標準化されたメッセージフォーマットの利用

一貫したフォーマットはバックエンド統合、デバッグ、スキーマ管理を容易にします。

- JSONやProtocol Buffersなど標準フォーマットを使用する。
- 必要なメタデータを含む明確なメッセージ構造を定義する。
- タイムスタンプ、デバイスID、メッセージタイプを含めることを検討する。
- 長期的なスキーマ進化を考慮し、スキーマバージョンフィールドを追加して互換性管理を簡素化する。

#### ペイロード内容の最適化

小さく整ったペイロードは伝送速度を上げ、特に制約のあるネットワークで輻輳リスクを減らします。

- 不要または冗長なフィールドを削除する。
- 短く意味のあるフィールド名を使用する。
- 圧縮アルゴリズムの適用を検討する。
- 繰り返しや頻繁に変化するデータは、差分更新などのインクリメンタル送信を検討する。

## 共有サブスクリプション

共有サブスクリプションはMQTT 5.0の機能で、複数クライアントが同一トピックをサブスクライブし、メッセージ負荷を共有できます。これによりロードバランシングやフェイルオーバーが組み込みで実現され、バックエンドサービスのスケーリングと高可用性に最適です。

EMQX Cloudは共有サブスクリプションを完全にサポートし、クライアントが共有グループIDのもとで協調してデータを消費できます。

### 構文と形式

共有サブスクリプションの形式はMQTT 5.0標準に準拠します。

```
$share/{group_id}/{topic_filter}
```

- `group_id`：共有サブスクリプショングループ識別子。異なるグループを区別するために使用。
- `topic_filter`：通常のサブスクリプションで使うトピックフィルター。

**例**

共有グループ`group1`で`sensor/data`トピックを3クライアントが共有サブスクライブする場合：

```
$share/group1/sensor/data
```

### 共有サブスクリプションの利点

共有サブスクリプションはMQTTクライアントアーキテクチャのスケーラビリティとレジリエンスを高める強力なツールです。

- **ロードバランシング**  
  同一グループ内のクライアントにメッセージが均等に分配され、単一クライアントのボトルネック化を防ぐ。

- **自動フェイルオーバー**  
  クライアント切断時、EMQXは未配信メッセージをグループ内の他クライアントに再配信し、サービス継続性と信頼性を確保。

- **高可用性**  
  高同時接続や大規模デバイスアクセスシナリオで、バックエンドシステムの応答性とフォールトトレランスを維持。

### 共有サブスクリプションの制限

共有サブスクリプションには利点がある一方で、すべてのワークロードに適しているわけではありません。

- **パフォーマンス劣化**  
  共有グループのクライアント数増加はメッセージ分配効率に影響を与える可能性がある。

- **非常に高いスループットには不向き**  
  1秒あたり5,000メッセージ以上の処理が必要な場合は、EMQXのデータ統合機能を使いKafkaなど外部メッセージングシステムへブリッジすることを推奨。

- **中規模ワークロードに最適**  
  共有サブスクリプションは中程度のボリューム環境での水平スケーリングに適している。超高スループットには専用のメッセージングパイプラインを利用する。

### 一般的なユースケース

共有サブスクリプションは以下のシナリオで特に効果的です。

- **バックエンドサービスのスケーリング**：複数のサービスインスタンスが共通トピックのデバイスデータを共同処理。
- **ロードバランシング**：複数クライアント間でMQTTトラフィックを分散。
- **高可用性アーキテクチャ**：サービス冗長化とフェイルオーバーの実装。

::: tip

5,000メッセージ/秒を超える高スループットシナリオでは、MQTT共有サブスクリプションに依存せず、データ統合を通じてKafkaなどのメッセージキューシステムにブリッジすることを推奨します。

:::

## 保持メッセージ

保持メッセージはMQTTプロトコルの機能で、ブローカーがトピックに最後にパブリッシュされたメッセージを保存し、その後にサブスクライブしたクライアントに自動送信します。これにより、新規サブスクライバーは次のパブリッシュを待たずに最新の状態や設定情報を即座に受け取れます。

EMQXブローカーは保持メッセージを完全にサポートし、メッセージ有効期限など追加の制御も提供します。

### 保持メッセージの利用シーン

保持メッセージは、クライアントがサブスクライブ直後に最新の既知値にアクセスする必要がある場合に有効です。

代表的なユースケース：

- **デバイス初期化**  
  デバイスがオンラインになった際に最新の状態や設定を提供。

- **ブロードキャスト通知**  
  グローバルなアナウンスメッセージ（例：システム通知）の共有。

- **監視・診断**  
  ヘルスチェックや診断データを常にサブスクライバーに提供。

- **設定配布**  
  デバイス設定を保存・配布し、常に最新バージョンを受信可能にする。

### 保持メッセージのパブリッシュとクリア方法

MQTTで保持メッセージを使うには、パブリッシュ時に`retain`フラグを`true`に設定します。保持メッセージを削除するには、同じトピックに空ペイロードで`retain`フラグを有効にしてパブリッシュします。

```
# 保持メッセージの設定
publish(topic="sensor/status", message="Device online", retain=True)

# 保持メッセージのクリア
publish(topic="sensor/status", message="", retain=True)
```

### 保持メッセージのベストプラクティス

本番環境で保持メッセージを効果的かつ安全に利用するため、以下の推奨事項を考慮してください。

- **使用は最小限に**  
  保持メッセージはブローカーのメモリを消費するため、特に動的・頻繁更新データでの過剰使用は避ける。

- **メッセージ有効期限を設定**  
  対応する場合は有効期限を定義し、古い情報が新規サブスクライバーに配信されるのを防ぐ。

- **ペイロードは小さく保つ**  
  フラグやステータス更新、設定ハッシュなど簡潔なデータ向け。大きなペイロードやファイルには不向き。

- **最新状態のみ保持**  
  デバイスのオンライン状態や現在設定、最後の既知値など「最新値」の意味が明確なシナリオに適用。

- **保持トピックでのワイルドカードサブスクライブを避ける**  
  クライアントがワイルドカード（例：`sensor/#`）でサブスクライブすると、該当するすべての保持メッセージが配信され、パフォーマンスが低下する可能性がある。保持メッセージのトピックは特定のフィルターでサブスクライブする。

- **古い状態は積極的にクリア**  
  ビジネス状態が無効になったら保持メッセージを速やかにクリアし、新規サブスクライバーの誤認を防ぐ。

## Last Will and Testament (LWT)

Last Will and Testament（LWT）は、クライアントの異常切断を検知し通知するMQTT標準機能です。クライアントが正常に切断しない場合（電源断やネットワーク断など）、ブローカーが事前に設定されたLWTメッセージを指定トピックに自動パブリッシュします。これにより他システムはリアルタイムに切断を検知し対応可能です。

EMQX CloudはLWTをサポートし、トピック、ペイロード、QoS、保持設定を柔軟に制御できます。

### 一般的なユースケース

LWTはクライアント側障害検知とシステム対応の重要な仕組みです。

- **デバイス状態監視**  
  デバイスが予期せず切断された際にダッシュボードや監視システムを更新。

- **障害アラート**  
  重要デバイスのオフライン時に自動アラーム、メール通知、ログ記録をトリガー。

- **リソースクリーンアップ**  
  切断デバイスに紐づくバックエンドリソースの解放や再割り当てを通知。

### 設定ガイドライン

LWTを効果的に設定するため、以下のベストプラクティスを推奨します。

- **トピック**  
  `status/{client_id}`のような専用トピック構造を用い、LWTメッセージを明確かつ一貫して配信。

- **メッセージ内容**  
  ペイロードは簡潔にし、デバイスID、タイムスタンプ、状態（例："offline"）など必要なメタデータを含める。

- **QoSレベル**  
  信頼性とネットワークコストのバランスを考慮し、多くの場合は**QoS 1**を推奨。

- **保持フラグ**  
  新規サブスクライバーがデバイスのオフライン状態を即座に認識できるよう、`retain`フラグを設定することを検討。

- **正常切断時の処理**  
  正常切断はLWTをトリガーしないため、切断前にクライアント側でオフライン状態をパブリッシュするか、オンライン状態をクリアすることが望ましい。

## セキュリティのベストプラクティス

MQTTクライアント構築においてセキュリティは極めて重要です。特にIoTやエンタープライズ環境では、デバイスとサービス間で機密データがやり取りされるため、強力な認証、認可、暗号化機構が必要です。EMQXはこれらをサポートし、安全なMQTT通信を実現します。

本セクションでは、クライアント側のセキュリティに関するベストプラクティスを、ID管理、アクセス制御、トランスポート層保護に分けて解説します。

### クライアント認証と認可

安全なクライアント識別と厳格な権限管理は、安全なMQTT環境の基盤です。

#### 証明書ベース認証

デジタル証明書は強力で検証可能なクライアントIDを提供し、スケーラブルなデバイスプロビジョニングを支援します。

- MQTTクライアント認証にX.509証明書を使用する。
- キーの定期更新を保証する証明書ローテーションポリシーを実装する。
- クライアント側で証明書と秘密鍵を安全に保管し、不正アクセスや漏洩を防ぐ。

#### ユーザー名／パスワードまたはトークン認証

ユーザー名とパスワード認証は一般的かつ柔軟で、既存認証システムとの統合が容易です。

- 本番環境では匿名接続を無効にする。
- 強力なパスワードを使用し、定期的な資格情報のローテーションをサポートする。
- 認証失敗後のリトライ間隔を遅延させ、ブルートフォース攻撃を防ぐ。

#### アクセス制御

細粒度のアクセス制御により、クライアントが許可されていないトピックのパブリッシュやサブスクライブを防止します。最小権限の原則に従い、各デバイスやクライアントに必要最低限の権限のみを付与してください。ACL制約にはクライアントID、ユーザー名、トピック階層を組み合わせて使用し、パブリッシュ権限とサブスクライブ権限を分離して過度なアクセスを避けることが重要です。

### トランスポート層のセキュリティ

クライアントとブローカー間の通信を暗号化し、データの整合性と機密性を保護します。

#### TLS/SSL暗号化

Transport Layer Security（TLS）は、メッセージ伝送中の盗聴や改ざんを防ぎます。

- すべてのMQTTクライアント接続にTLS 1.2以上を使用する。
- 非推奨または安全でない暗号スイートを除去するため、TLS設定を定期的に監査・更新する。
- 中間者攻撃を防ぐため、証明書検証を有効にする。
- 高セキュリティシナリオでは相互TLS（mTLS）を有効にする。
- 本番環境での平文MQTT接続は避ける。

#### プロトコル強化と検証

安全なプロトコルレベルのデフォルトを強制し、全体のセキュリティ姿勢を強化します。

- 安全でないプロトコルバージョンや暗号スイートを無効化する。
- セッション開始前にクライアント側でブローカー証明書を検証する。
- 証明書失効確認機構を実装する。

## デバイスイベントログ

EMQXはリアルタイムメッセージルーティングに特化した高性能MQTTブローカーですが、多くのアプリケーションでは監視、分析、トラブルシューティングのためにデバイス活動やシステムイベントの包括的なログ記録が必要です。

本セクションでは、EMQX Cloudの組み込みEvent Topicsおよびデータ統合機能を活用し、イベントログ機能を拡張する方法を説明します。

### ブローカー側イベントストレージの制限理解

EMQXは設計上、メッセージ内容の永続化やデバイス活動の履歴保存を行いません。リアルタイム配信と接続状態管理に注力しています。

#### EMQXブローカーの役割

- MQTTメッセージのリアルタイムルーティングと配信を担当。
- メッセージペイロードや履歴イベントログは保存しない。
- 接続状態とルーティング情報のみを管理。
- 履歴イベント追跡機能は提供しない。

完全な可観測性やメッセージ監査、長期保存を実現するには、EMQXのデータ統合機能を用いてイベントデータを外部システムに転送する必要があります。

### データ統合によるイベント記録

実際のIoT展開では、単なるメッセージ配信を超えた包括的なイベントログが求められます。EMQX Cloudはイベント駆動型のデータ統合をサポートし、運用イベントを外部システムにエクスポートして監視、分析、監査、デバッグに活用可能です。

開発者が記録すべき代表的なイベントカテゴリは以下の通りです。

- デバイス接続／切断イベント
- サブスクリプション／解除アクティビティ
- メッセージ内容とメタデータ
- 認証・認可イベント

#### 利用可能なイベントトピック

EMQX Cloudは`$events/`ネームスペース以下に多様なシステムイベントトピックを提供します。これらは内部ブローカーイベントを公開し、クライアント挙動、メッセージ配信、セキュリティ関連操作をリアルタイムに監視可能にします。

| カテゴリ           | トピック                                 | 説明                                   |
| ------------------ | --------------------------------------- | ------------------------------------ |
| **クライアントイベント** | `$events/client_connected`              | クライアント接続                      |
|                    | `$events/client_disconnected`           | クライアント切断                      |
|                    | `$events/client_connack`                 | 接続確認応答送信                      |
|                    | `$events/client_subscribed`              | クライアントがトピックをサブスクライブ |
|                    | `$events/client_unsubscribed`            | クライアントがトピックを解除          |
|                    | `$events/client_check_authn_complete`    | 認証チェック完了                      |
|                    | `$events/client_check_authz_complete`    | 認可チェック完了                      |
| **セッションイベント** | `$events/session_created`               | 新規セッション作成                    |
|                    | `$events/session_terminated`             | セッション終了                        |
|                    | `$events/session_subscribed`             | セッション内でのトピックサブスクライブ |
|                    | `$events/session_unsubscribed`           | セッション内でのトピック解除          |
| **メッセージイベント** | `$events/message_delivered`             | クライアントへのメッセージ配信        |
|                    | `$events/message_dropped`                 | 転送中にメッセージ破棄                |
|                    | `$events/message_acked`                   | クライアントによるメッセージアック    |
|                    | `$events/delivery_dropped`                | クライアント配信時のメッセージ破棄    |

### 実装戦略

デバイス活動ログと可観測性を有効にするため、以下の3ステップを推奨します。

#### ステップ1：データ統合ルールの設定

- EMQX Cloudコンソールで特定のイベントトピック（例：`$events/client_connected`）にマッチするルールを定義。
- 必要に応じてSQLライクなフィルターや条件マッチングを使用。

#### ステップ2：ストレージまたはストリーミングバックエンドの選択

ユースケースに応じて適切な宛先を選択：

- **時系列データベース**：InfluxDB、TimescaleDB（メトリクス・傾向可視化用）
- **リレーショナルデータベース**：MySQL、PostgreSQL（構造化イベント記録用）
- **ドキュメントストア**：MongoDB、Elasticsearch（柔軟なクエリ・イベント保存用）
- **データウェアハウス**：BigQuery、Redshift（分析・レポーティング用）
- **ストリーミングシステム**：Kafka、RabbitMQ（リアルタイムイベントストリーム用）
- **クラウドストレージ**：AWS S3、Alibaba Cloud OSSなど（長期アーカイブ用）

#### ステップ3：イベントデータの処理と保存

- メタデータ（テナントID、地理情報など）でイベントデータをパース・付加。
- ノイズを減らすためフィルターを適用し、関連イベントに絞る。
- 下流サービス向けにイベントフォーマットを正規化・変換。
- コンプライアンスや監査要件に応じた履歴データの保存期間ポリシーを実装。

### イベント記録のベストプラクティス

#### イベントフィルタリング

- 必要なイベントタイプのみをサブスクライブし、過剰なデータ量を回避。
- クライアント側で特定デバイス、地域、製品タイプのフィルターを適用。
- ワイルドカード使用時は過剰サブスクライブを避けるため慎重に。

#### データフォーマットと整合性

- システム間・統合間で標準イベントスキーマを定義。
- 以下の必須メタデータを含める：  
  - タイムスタンプ  
  - クライアントIDまたはデバイスID  
  - イベントタイプ
- パイプライン内でデータ検証とエラーハンドリングを実装。

#### パフォーマンス考慮

- イベント転送パイプラインのスループットとレイテンシを監視。
- 大量イベントストリーム向けにバッファリング機構を導入。
- 非クリティカルなイベントはバッチ処理でオーバーヘッドを削減。

#### プライバシー保護

- 保存前に機密メッセージ内容をマスクまたは暗号化し、情報漏洩を防止。

#### セキュリティとコンプライアンス

- イベントデータの送受信および保存はすべて暗号化を適用。
- ロギングバックエンドへのアクセス制御を実施し機密データを保護。
- ローカル規制に基づくデータ保持・プライバシーポリシーを策定・遵守。

#### データバックアップ

- 重要なイベント記録の保護のため、バックアップおよびリカバリ機構を確立。

### 監視とアラート

イベントログを監視・アラートシステムと統合し、問題検知と自動対応を実現。

#### 実用的なアラート例

重要イベントを監視し、以下のようなアラートを設定：

- **オフライン検知**：重要デバイスが予期せず切断された際の通知。
- **サブスクリプション異常**：異常なサブスクリプションパターンや悪用の検出。
- **配信失敗**：ドロップされたメッセージや未アックのQoS 1/2メッセージの監視。
- **認証失敗**：繰り返しのログイン失敗を追跡しセキュリティ監査に活用。

#### 分析とレポーティング

保存されたイベントデータを用いて：

- デバイス接続性分析
- 利用パターン分析
- パフォーマンス最適化の洞察
- コンプライアンス報告・監査

イベントトピックとデータ統合の詳細設定については、[Data Sources and Fields](../rule_engine/rule_engine_events.md)を参照してください。

## クォータと制限

EMQX Cloudは、デプロイプランやリソース仕様に応じて接続数、サブスクリプション数、メッセージレート、データスループットなどの使用制限を設けています。

最新かつ詳細なクォータ情報は、[Quotas and Limits](../create/restriction.md)を参照してください。

## まとめ

本ガイドでは、EMQX Cloudを利用した効率的で安定かつ安全なMQTTクライアント開発のための基本的なベストプラクティスを紹介しました。これらの推奨事項に従うことで、クライアントのパフォーマンスを最適化し、スケール時のEMQXとの統合を円滑に行えます。

主なポイントは以下の通りです。

- **接続管理**  
  自動再接続やセッション永続化戦略を用いて堅牢なクライアント接続を確立する。

- **トピックサブスクリプション設計**  
  構造化されたトピック階層とワイルドカードを適切に使い、複雑さを減らし効率を向上。

- **QoS設定**  
  ビジネス要件に応じて適切なQoSレベルを選択し、信頼性とパフォーマンスのバランスを取る。

- **共有サブスクリプション**  
  MQTT 5.0の共有サブスクリプションを活用し、バックエンドのスケーリング、ロードバランシング、フェイルオーバーを実現。

- **セキュリティ対策**  
  強力な認証、認可、TLS暗号化を通じてエンドツーエンドのセキュリティを確保。

- **イベントログとデータ統合**  
  EMQXのルールエンジンとイベントトピックを利用し、運用データを外部システムに転送して可観測性と分析を強化。

大規模なIoTデバイス接続やエンタープライズグレードのメッセージングサービス構築において、本ベストプラクティスの遵守はシステムの安定性と効率性を大幅に向上させます。

EMQX Cloudの公式クォータ制限ドキュメントを必ず確認し、プラットフォーム仕様に準拠したアプリケーション設計を行ってください。

より複雑なユースケースには、EMQX Cloudの高度な機能を活用してさらなる最適化とスケーラビリティの実現を目指しましょう！
