第17章 フロー制御
フロー制御は、クライアントとサーバー間、またはあるサーバーと別のサーバー間のデータのフローを制限するために使用されます。これは、クライアントまたはサーバーがデータでいっぱいにならないよう行われます。
17.1. コンシューマーフロー制御 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
これは、クライアントがメッセージを消費する場合に、サーバーとクライアント間のデータのフローを制御します。パフォーマンス上の理由から、通常、クライアントは、
receive() メソッドを使用してコンシューマーに配信するか、メッセージリスナーで非同期的にコンシューマーに配信する前にメッセージをバッファーします。メッセージは、メッセージが配信され、内部バッファーにインストールされたときにコンシューマーがメッセージをすぐに処理できない場合に構築できます。これにより、メッセージを時間内に処理できない場合にクライアントでメモリーが足りなくなることがあります。
17.1.1. ウィンドウベースフロー制御 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
HornetQ コンシューマーでは、メッセージをクライアントに渡して消費する前にクライアントサイドで特定の数のメッセージをバッファーすることによってパフォーマンスが向上します。
各メッセージに対してネットワークラウンドトリップを回避するために、HornetQ は、各コンシューマーでバッファーにメッセージをプレフェッチします。各コンシューマーでバッファーされるメッセージの最大サイズ (バイト単位) は、
consumer-window-size パラメーターによって決定されます。
デフォルトでは、
consumer-window-size が 1 MiB (1024 * 1024 バイト) に設定されます。
値は以下のとおりです。
- バインドされないバッファーの場合は
-1 - メッセージをバッファーしない場合は
0 - 該当する最大サイズ (バイト単位) のバッファーの場合は
>0。
コンシューマーウィンドウサイズを設定すると、メッセージング使用ケースに応じてパフォーマンスが大幅に向上することがあります。例として、次の 2 つのケースを考えてみます。
- 高速なコンシューマー
- 高速なコンシューマーは、メッセージを消費するとすぐにメッセージを処理できます。高速なコンシューマーを許可するには、
consumer-window-sizeを -1 に設定します。これにより、クライアントサイドでバインドされないメッセージバッファリングが許可されます。この設定は注意して使用してください。これは、コンシューマーがメッセージを受信したときにすぐにメッセージを処理できない場合に、クライアントのメモリーをオーバーフローすることがあります。 - 低速なコンシューマー
- 低速なコンシューマーの場合は、各メッセージを処理するのに大幅な時間がかかります。したがって、クライアントサイドでメッセージのバッファリングを回避し、メッセージを別のコンシューマーに代わりに配信できることが望まれます。キューが 2 つのコンシューマーを持つ状況を考えます (このうちの 1 は非常に低速です)。メッセージは循環形式で両方のコンシューマーに配信されます。高速なコンシューマーは、バッファーが空になるまですべてのメッセージを非常に速く処理します。この時点で、低速なコンシューマーのバッファーには処理したいメッセージが引き続き存在し、高速なコンシューマーによってメッセージが処理されることが回避されます。したがって、高速なコンシューマーは、他のメッセージを処理できる場合にアイドル状態になります。低速なコンシューマーを許可するには、
consumer-window-sizeを 0 (バッファーなし) に設定します。これにより、低速なコンシューマーがクライアントサイドでメッセージをバッファーすることが回避されます。メッセージは、サーバーサイドで保持され、他のコンシューマーが消費できる状態になります。これを 0 に設定すると、キューの複数のコンシューマー間で明確なディストリビューションが提供されます。
ほとんどのコンシューマーは高速または低速なコンシューマーとして明確に識別できず、その中間になります。この場合、パフォーマンスを最適化するための
consumer-window-size の値の設定は、メッセージング使用ケースに基づき、最適な値を見つけるためにベンチマークが必要です。ただし、ほとんどの場合は、1MiB の値で適切です。
17.1.1.1. コア API の使用 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
HornetQ コア API が使用された場合、コンシューマーウィンドウは
ClientSessionFactory.setConsumerWindowSize() メソッドと ClientSession.createConsumer() メソッドのいくつかによって指定されます。
17.1.1.2. JMS の使用 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
接続ファクトリーをルックアップするために JNDI が使用される場合、コンシューマーウィンドウサイズは
JBOSS_DIST/jboss-as/server/PROFILE/deploy/hornetq/hornetq-jms.xml で設定されます。
接続ファクトリーが直接インスタンス化される場合、コンシューマーウィンドウサイズは
HornetQConnectionFactory.setConsumerWindowSize() メソッドで指定されます。
17.1.2. レート制限フロー制御 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
コンシューマーがメッセージを消費できるレートを制御することもできます。これは、コンシューマーが指定されたレートよりも速いレートでメッセージを消費しないようにするために使用できます。
この機能を有効にするためにレートは、正の整数である必要があり、1 秒あたりのメッセージ単位で指定された最大メッセージ消費レートです。これを
-1 に設定すると、レート制限フロー制御が無効になります。デフォルト値は -1 です。
17.1.2.1. コア API の使用 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
HornetQ コア API が使用された場合、レートは
ClientSessionFactory.setConsumerMaxRate(int consumerMaxRate) メソッドまたは ClientSession.createConsumer() メソッドの一部によって設定できます。
17.1.2.2. JMS の使用 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
接続ファクトリーをルックアップするために JNDI が使用される場合、最大レートは
JBOSS_DIST/jboss-as/server/PROFILE/deploy/hornetq/hornetq-jms.xml で設定できます。
接続ファクトリーが直接インスタンス化される場合、最大レートサイズは
HornetQConnectionFactory.setConsumerMaxRate(int consumerMaxRate) メソッドで設定できます。
注記
レート制限フロー制御は、ウィンドウベースのフロー制御とともに使用できます。レート制限フロー制御は、クライアントが 1 秒間に消費できるメッセージの数にのみ影響を与え、バッファーにあるメッセージの数には影響を与えません。低速なレート制限と大きいウィンドウベース制限がある場合は、クライアントの内部バッファーがすぐにメッセージで満たされます。