2

名前付き JMS キューを介して JMS リクエストを Weblogic 10.3 サーバーに送信し、一時キューを介して返信を受け取ります。

クライアント (ベアボーン):

//init
Destination replyQueue = session.createTemporaryQueue();
replyConsumer = session.createConsumer(replyQueue);
...
//loop
TextMessage requestMessage = session.createTextMessage();
requestMessage.setText("Some request")
requestMessage.setJMSReplyTo(replyQueue);
requestProducer.send(requestMessage);
Message msg = replyConsumer.receive(5000);
if (msg instanceof TextMessage) {
    ...
} else { ... }
//loop end

サーバー MDB (メッセージ駆動型 Bean):

public void onMessage(Message msg) {
    if (msg instanceof TextMessage) {
        ...
        TextMessage replyMessage = jmsSession.createTextMessage();
        replyMessage.setText("Some response");
        replyMessage.setJMSCorrelationID(msg.getJMSCorrelationID());
        replyProducer.send(replyMessage);
    }
}

問題は、最初のサーバー応答がしばしば失われることです! つまり、replyConsumer.receive(5000)4 ~ 5 番目の replyConsumer ごとにタイムアウトで終了します。コンシューマーが最初の応答を受信すると、残りのすべてを受信し続けるため、一時キューが作成された後に一時キューを介して送信される最初のメッセージのみに問題があります。

私の質問:作成後に最初から機能するために、一時キューに特別なものを設定する必要がありますか? または他のヒントはありますか?

詳細情報:

  • 私のローカル開発マシンに対してテストすると、一時キューは問題なく動作します。メッセージが失われるのは、クラスター化された Weblogic サーバーに対してテストした場合のみです。ただし、1 つのインスタンスを除くすべてのクラスター メンバーをオフにしました。
  • サーバーがクライアントが送信するすべての要求に正常に応答することを確認しました(送信された要求と送信された応答をカウントすることによって)。サーバーは、応答が失われた場合でも、ミリ秒単位で応答します。
  • 一時キューを通常の名前付きキューに置き換えると、問題はなくなります! したがって、問題は(私には)私のコードにあるようには見えません。
  • また、返信メッセージの有効期限、永続性、遅延などを変更しようとしましたが、成功しませんでした。このようにして、クライアントがキューの読み取りを開始する前に応答が到着し、メッセージがすぐに期限切れになり、クライアントに処理の機会が与えられないというシナリオを除外しました。
  • 編集:同期の代わりにreplyConsumer.receive(5000)、非同期も使用しようとしましたreplyConsumer.setMessageListener(this)。動作は変わっていません。最初のメッセージはまだ一時キューで失われています。

編集:使用している Weblogic サーバー (またはクラスター) に問題があるようです。サーバー アプリケーションを別の Weblogic クラスタにデプロイしたところ、すべてが正しく機能し始めたからです。両方のクラスターは同じように構成する必要があります。では、どこが違うのでしょうか? Weblogic がエラーを通知しないのは恐ろしいことです。

4

1 に答える 1

1

問題は、コンシューマーが受信を開始する前に、サーバーが公開を受信して​​破棄している場合があることです。

これを回避する方法は、現在のブロッキング呼び出し(replyConsumer.receive(5000))の代わりに非同期受信(replyConsumer.setMessageListener)呼び出しを使用し、残りのコンシューマーコードとともに呼び出しをコードに追加することです。

そうすれば、リクエストを送信する前に、すでに返信をリッスンしています。

お役に立てば幸いです。

編集:あなたが一時的なキューを使用していることを読んでください、それで私の最初の文は正しくありません。ただし、実験として、残りの応答を試して、表示されている動作が変わるかどうかを確認してください

于 2012-04-10T13:19:11.747 に答える