Skip to content

メッセージロスのトラブルシューティング方法

メッセージロスは通常、慎重な検討と追跡が必要な2つの状況に関係します。

EMQXでサブスクライブされていない場合のメッセージドロップ

この状況は、メッセージがすでにEMQXに到達しているものの、サブスクライバーが存在しないためにメッセージがドロップされる場合に発生します。具体的なドロップ統計は、デプロイメントコンソールの「Messages」セクション内の「Unsubscribed Message Count」で確認できます。

サブスクライブされていない場合のドロップメトリクス

これらのドロップされたメッセージを追跡するには、イベントトピック $events/message_dropped を利用できます。メッセージがドロップされるたびにイベントがトリガーされ、関連するメッセージ情報がこのイベントトピックに送信されます。これにより、メッセージドロップイベントをサードパーティシステムに送信して記録し、後続の問題調査に活用できます。

メッセージ配信中にEMQXがメッセージをドロップする場合

この状況は、メッセージがサブスクライバーに届いているものの、何らかの理由で正常に配信されていない場合を指します。理由としては、クライアントがClean SessionをFalseに設定して長時間オフラインであったり、クライアントのメッセージ処理能力が不足していることなどが挙げられます。以下はメッセージ配信失敗につながる可能性のあるシナリオです。

a. クライアントがClean SessionをFalseに設定し、長時間オフラインのためにメッセージがロスする場合

この場合、クライアントがオフラインでもEMQXはメッセージを送信しようとします。配信に失敗したメッセージはクライアントのメッセージキューに蓄積され、クライアントの再接続を待ちます。クライアントのオフライン期間が長すぎる場合(MQTT v3プロトコルではデフォルト2時間、MQTT v5プロトコルではsession_expiry_intervalの値で決定)、またはクライアントがこれらのメッセージを迅速に処理できない場合、メッセージがドロップされる可能性があります。

このシナリオの対策としては、クライアントが再接続時に大量のデバイスのオンライン/オフラインメッセージが蓄積されないように、Clean SessionをTrueに設定することが挙げられます。もしClean SessionをFalseに設定する場合は、クライアントの長時間のダウンタイムを防ぐために自動再接続機能を実装してください。また、ランダムなクライアントIDの使用は避けてください。ランダムクライアントIDを使用しClean SessionをFalseにすると、クライアント再接続時にセッションが変わり、メッセージロスが発生する可能性があります。

b. クライアントのメッセージ処理能力が不足している場合

具体的には、クライアントが複数のトピックをサブスクライブしている場合、これらのメッセージは固定長のメッセージキュー(デフォルトは1,000)を共有します。あるトピックのメッセージが過剰に蓄積し、キューの長さ制限を超えるとメッセージロスが発生します。したがって、クライアント側のメッセージ処理能力不足により、一部のメッセージがサブスクライバーに正常に配信されないことがあります。

このシナリオの対策としては以下が挙げられます。

関連統計は、デプロイメントコンソールの「Metrics」内の「Dropped Messages」セクションで確認できます。

メッセージキュー満杯によるドロップメトリクス

さらに、デプロイメントログでエラータイプを「Message」に選択すると、「[Session] Dropped msg due to mqueue is full: Message」などの類似レコードを検索でき、より詳細な情報を取得可能です。

メッセージキュー満杯によるドロップログ

これらのメッセージロスイベントを追跡するには、イベントトピック $events/delivery_dropped を利用できます。メッセージ配信が失敗するたびにイベントがトリガーされ、関連メッセージ情報がこのイベントトピックに送信されます。さらに、メッセージ配信失敗イベントをサードパーティシステムに送信して記録し、後続の問題調査に活用できます。

まとめると、以下のSQLルールを使って関連イベントをフィルタリングできます。

sql
SELECT 
*

FROM "$events/message_dropped", "$events/delivery_dropped"

WHERE topic =~ 'xxx'

このSQLルールは、特定のトピック(例:'xxx')に関連するメッセージドロップイベントをフィルタリングし、さらなる分析や対応に役立てます。メッセージスループットが高い場合は、クライアントIDなどの追加フィルタリング項目を加えることを検討してください。利用可能なフィルタリング項目については、イベントトピック - メッセージイベントをご参照ください。