インフライトおよびメッセージキュー
はじめに
メッセージのスループットを向上させ、ネットワークの変動による影響を軽減するために、EMQXは複数の未アック済みのQoS 1およびQoS 2メッセージを同時にインフライト状態に保つことができます。送信済みで未確認のメッセージは、アックが完了するまでインフライトウィンドウに格納されます。
インフライトメッセージの数が制限値、すなわちインフライトウィンドウの長さ制限(max_inflight
参照)を超えた場合、EMQXはそれ以上のメッセージを送信せず、これらのメッセージをメッセージキューに格納します。インフライトウィンドウ内のメッセージがアックされると、メッセージキュー内のメッセージが先入れ先出し(FIFO)順に送信され、インフライトウィンドウに格納されます。
QoS 1およびQoS 2のインフライトメッセージ数がインフライトウィンドウの最大制限(max_inflight
参照)に達すると、新たに到着したメッセージは即座に転送されず、一時的にメッセージキューに保存されます。
メッセージキュー内のメッセージはFIFO順に送信され、前のメッセージが確認されて削除された後にのみインフライトウィンドウに追加されます。ただし、QoS 0メッセージはこのプロセスの影響を受けず、常に即座に転送されます。
メッセージキューも長さ制限に達した場合、以降のメッセージは引き続きメッセージキューにキャッシュされますが、メッセージキュー内の最も古いメッセージが破棄されます。したがって、適切なメッセージキューの長さ制限(max_mqueue_len
参照)を設定することが非常に重要です。
また、メッセージキューはサブスクライバーがオフラインの間に到着したメッセージ(QoS 0メッセージを含む)を保存し、サブスクライバーが次回オンラインになった際に送信するためにも使用されます。QoS 0メッセージは重要度が低い場合があるため、EMQXがQoS 0メッセージをキューに保存するのを無効にすることも可能です(mqueue_store_qos0
参照)。
なお、インフライトウィンドウとメッセージキューはグローバルではなく、EMQXは各クライアント接続ごとに個別のインフライトウィンドウとメッセージキューを割り当てます。
インフライトウィンドウとReceive Maximum
MQTT v5プロトコルはCONNECTパケットにReceive Maximum
属性を追加しており、その公式説明は以下の通りです。
クライアントは、この値を使用して、同時に処理可能なQoS 1およびQoS 2のパブリッシュメッセージの最大数を制限します。サーバーが送信しようとするQoS 0のパブリッシュメッセージを制限する仕組みはありません。
つまり、サーバーはアックを待つ間に異なるメッセージ識別子を持つPUBLISHパケットをクライアントに送信できますが、未アックメッセージ数がReceive Maximum
の制限に達するまで送信可能です。
このことから、Receive Maximum
は実質的にEMQXのインフライトウィンドウ機構と同じであることがわかります。ただし、EMQXはMQTT v5.0プロトコルがリリースされる前からこの機能をMQTTクライアントに提供していました。現在、MQTT v5.0プロトコルを使用するクライアントはReceive Maximumの仕様に従ってインフライトウィンドウの最大長を設定し、以前のバージョンのMQTTプロトコルを使用するクライアントは従来通り設定に基づいて設定されます。
ただし、EMQXはCONNECTパケットで要求されたReceive Maximum
の値を必ずしも許可するわけではありません。代わりに、CONNACKパケットで許可されるReceive Maximum
はmqtt.max_inflight
設定によって上限が制限されます。
設定項目
設定項目 | 型 | オプション値 | デフォルト値 | 説明 |
---|---|---|---|---|
mqtt.max_inflight | integer | (0, 65536) | 32 | インフライトウィンドウの長さ制限。0は無制限を意味します |
mqtt.max_mqueue_len | integer | [0, ∞) | 1000 | メッセージキューの長さ制限。0は無制限を意味します |
mqtt.mqueue_store_qos0 | enum | true , false | true | クライアントがオフライン時にEMQXがQoS 0メッセージをメッセージキューに保存するかどうか |