# メッセージドロップアラート

メッセージドロップアラートは、クライアントセッションのメッセージキューが配信中に満杯になったため、EMQX Cloudがメッセージをドロップしたことを示します。

これは通常、メッセージがサブスクライバーのセッションにルーティングされたものの、クライアントが長時間オフラインのままであったか、メッセージを処理する速度が追いつかなかったことを意味します。セッションキューが制限に達すると、それ以降のメッセージはキューに入れられずドロップされます。

## クライアントが長時間オフラインの場合（Clean Session = False）

### 症状

クライアントがオフラインで **Clean Session = False** の場合、EMQX Cloudはクライアントが再接続するまで、そのクライアントのセッションメッセージキューにメッセージを格納し続けます。デフォルトの最大長は1,000メッセージです。

クライアントがオフラインのままセッションが期限切れで削除される（MQTT v3ではデフォルト2時間、MQTT v5では `session_expiry_interval` で指定）か、クライアントが再接続する前にセッションキューが満杯になると、メッセージはドロップされます。

**Monitor** ページでは、クライアントはオフラインですがセッションは存在し、メッセージキューが制限に達している状態が確認できます。

### 主な原因

- クライアントが長時間オフラインのままである。
- メッセージが蓄積され、セッションキューの最大長に達している。
- クライアントがランダムな `clientid` を使い、`Clean Session = False` のため、再接続時に異なるセッションが作成される。

### 対処方法

- クライアントがオフライン時にメッセージを必要としない場合は、**Clean Session** を `True` に設定し、オフライン中のメッセージ蓄積を防止してください。
- **Clean Session** を `False` にする必要がある場合は、自動再接続を実装し、ネットワーク障害後は速やかに再接続してください。
- ランダムな `clientid` と `Clean Session = False` を組み合わせないでください。クライアントIDが変わるとセッションの再開ができなくなります。

## クライアントのメッセージ処理能力不足

### 症状

クライアントがサブスクライブしているすべてのトピックは、1つの固定長セッションメッセージキューを共有しており、デフォルトの最大長は1,000メッセージです。高ボリュームのトピックがクライアントの処理速度を上回ると、キューが満杯になり、それ以降のメッセージがドロップされます。

**Monitor** ページでは、クライアントはオンラインで、セッション詳細に **Message Queue Full (1000 / 1000)** と表示されます。

### 主な原因

- クライアントのメッセージ消費速度が生成速度に追いついていない。
- 1つのクライアントが多くの高ボリュームトピックをサブスクライブしている。

### 対処方法

- クライアントを最適化し、メッセージ処理および消費のスループットを向上させてください。
- 共有サブスクリプションを利用して、複数のクライアントにメッセージを分散してください。詳細は[共有サブスクリプション](../../connect_to_deployments/shared_subscription.md)を参照してください。

## トラブルシューティング

1. EMQX Cloudコンソールにログインします。

2. **Deployment Logs** を開き、**Error Type** を **Messages** に設定し、以下のようなメッセージドロップのエントリを探します。

   ```text
   clientid: device001, peername: xx.xx.xx.xx:23853, username: test, topic: t/test, pid: <0.13552.0>, payload: 61616161616161616161, payload_encode: hex, queue: {"store_qos0":true,"max_len":1000,"len":1000,"dropped":91530}, msg: dropped_msg_due_to_mqueue_is_full
   ```

3. ログエントリから `clientid` を控えます。

4. **Monitor** -> **Clients** に移動し、`clientid` を検索してセッション状態を確認します。

   - クライアントがオフラインでセッションが存在する場合は、「クライアントが長時間オフライン」のシナリオを調査してください。

     ![オフラインクライアントセッション](./_assets/message_loss_offline.png)

   - クライアントがオンラインでセッションメッセージキューが満杯の場合は、「クライアントのメッセージ処理能力不足」を調査してください。

     ![オンラインクライアントのメッセージキュー満杯](./_assets/message_loss_online.png)

5. **Monitor** -> **Clients** にセッションが表示されない場合は、クライアントログと Clean Session（Clean Start）設定を確認してください。

   - 設定が `True` の場合、メッセージドロップは通常クライアントの処理能力不足を示します。
   - 設定が `False` の場合は、クライアントの切断ログを比較し、長時間オフラインであったかを判断してください。

## モニタリングと統計

EMQX Cloudコンソールの **Metrics** -> **Timeline** -> **Dropped Messages** で、時間経過に伴うドロップメッセージの総数を監視できます。

![モニタリングタイムラインのドロップメッセージ](./_assets/message_loss_monitor.png)

## メッセージドロップイベントの追跡

- EMQX Cloudは、過去のセッションキューの完全な内容やドロップされたメッセージのすべてのデータを保持しません。
- ログには選択されたフィールドのみが含まれ、`payload` は切り詰められている場合があります。記録されるフィールドには `clientid`、`peername`、`username`、`topic`、`payload` があります。
- メッセージドロップを時間経過で追跡するには、`$events/delivery_dropped` イベントトピックのデータ統合ルールを作成し、イベントを転送または保存してください。例：

  ```sql
  SELECT
      *
  FROM
      "$events/delivery_dropped"
  ```

- `clientid` や `topic` などのフィールドでフィルタリングも可能です。詳細は[SQLデータソースとフィールド](../../rule_engine/rule_engine_events.md#message-dropped-when-delivering-event-events-delivery-dropped)を参照してください。
