2012-04-10 17 views
2

JMS要求をWeblogic 10.3サーバーに名前付きJMSキュー経由で送信し、一時キュー経由で返信を返します。JMS一時キューが最初のメッセージを破棄します

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

//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 

Serverの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がエラーを通知しないことを私に恐れている。

+0

私たちはこの悪い振る舞いの理由は見つかりませんでした。しかし、ドメインの再作成は助けになりました。新しいドメインは問題なく動作します。 – xarx

答えて

1

あなたの問題は、コンシューマーが受信を開始する前に、サーバーがパブリッシュを受信して​​破棄していることがあります。

あなたが現在持っているブロッキングコール(replyConsumer.receive(5000))の代わりに非同期のreceive(replyConsumer.setMessageListener)コールを使用し、残りのコンシューマのコードにコールを追加する方法ですコード。

このように、リクエストを送信する前に、すでに返信を待ち受けています。

希望に役立ちます。

編集:一時的なキューを使用していることを読み、最初の文章が正しくない。しかし、実験として、私の応答の残りの部分があなたが見ている動作を変更するかどうかを試してみてください

+0

私はあなたが提案したものを試しましたが、成功しませんでした。私は自分の投稿を編集し、さらに情報を追加しました。 – xarx

関連する問題