第14章 一時キューとランタイムキュー

クライアントがリクエストを送信して応答を待つリクエスト応答パターンを設計する場合、クライアントの各ランタイムインスタンスが応答専用キューを必要とするかどうか、ランタイムインスタンスが共有キューにアクセスできるかどうかを考慮し、適切な属性に基づいて具体的な応答メッセージを選択する必要があります。

複数のキューが必要となる場合、クライアントには動的にキューを作成する機能が必要になります。JMS は、一時キューの概念を使ってこの機能を提供します。Session によってリクエストに TemporaryQueue が作成されます。Connection の有効期間中 (たとえば接続を閉じるまで、または一時キューが削除されるまで) 存在します。つまり、一時キューは特定のセッションで作成されますが、同じ接続で作成された他のセッションで再利用できます。

共有キューと応答独自の一時キューを使用するトレードオフは、アクティブなクライアントインスタンスの見込み数に影響されます。共有キューアプローチでは、一部のプロバイダー固有のしきい値で、キューへのアクセスの競合が懸念される可能性があります。これは、ランタイム時にキューストレージを作成するプロバイダーによるオーバーヘッドの増加と、大量になる可能性のある一時キューを収容するマシンメモリーへの影響を比較する必要があります。

以下の例では、起動時に各クライアントに一時キューとコンシューマーを作成します。各メッセージの JMSReplyTo プロパティーを一時キューに設定し、次に各メッセージの相関 ID を設定してリクエストメッセージを応答メッセージと関連付けます。これにより、リクエストごとにコンシューマーを作成して閉じるというオーバーヘッド (非常に大きい) が回避されます。同じプロデューサーとコンシューマーは、多くのスレッドで共有またはプールできます。セッションの終了時に受信したもののまだ確認されていないメッセージはすべて保持され、コンシューマーが次にキューをアクセスすると再送されます。

例: 一時キューのコード

...
// Create a temporary queue, one per client
Destination temporaryQueue = session.createTemporaryQueue();
MessageConsumer responseConsumer = session.createConsumer(temporaryQueue);

// This class handles messages to the temporary queue
responseConsumer.setMessageListener(this);

// Create the message to send
TextMessage textMessage = session.createTextMessage();
textMessage.setText("My new message!");

// Set the reply to field and correlation ID
textMessage.setJMSReplyTo(temporaryQueue);
textMessage.setJMSCorrelationID(myCorrelationID);

producer.send(textMessage);
...

同様に、一時トピックは Session.createTemporaryTopic() メソッドを使用して作成されます。