質問
メッセージリスナーを一時的に無効にする良い方法は何でしょうか?私が解決したい問題は次のとおりです。
- JMS メッセージはメッセージ リスナーによって受信されます
- メッセージを処理しようとするとエラーが発生します。
- システムがメッセージを処理できるように再び準備が整うまで待ちます。
- システムの準備が整うまでは、これ以上メッセージを送信したくないので...
- ...メッセージリスナーを無効にしたいのですが。
- システムは再び処理できる状態になりました。
- 失敗したメッセージが処理され、JMS メッセージが確認応答されます。
- メッセージ リスナーを再度有効にします。
現在、Sun App Server を使用しています。MessageConsumer でメッセージ リスナーを null に設定して無効にし、setMessageListener(myOldMessageListener) を使用して再度有効にしましたが、その後メッセージを取得できなくなりました。
解決
システムがメッセージを再度処理する準備ができるまでonMessage()リスナーメソッドから戻らない場合はどうでしょうか?これにより、JMSはそのコンシューマで別のメッセージを配信できなくなります。
これは、非同期の場合にreceive()を呼び出さないことと同等の非同期です。
特定のJMSセッションにはマルチスレッドが存在しないため、onMessage()メソッドが戻るまでメッセージのパイプラインは保持されます。
setMessageListener()を動的に呼び出すことの意味についてはよく知りません。 javadocは、 there's 「メッセージが既存のリスナーまたは同期コンシューマによって消費されているとき」と呼ばれる場合の未定義の動作。 onMessage()内から呼び出している場合、その未定義のケースにヒットしているように聞こえます。
他のヒント
メッセージリスナをreceive()ループに置き換える回避策によって問題が解決しましたが、メッセージリスナを無効にしてすぐに有効にする方法に興味があります。
メッセージは配信されているように見えますが、リスナーが接続されていないため、メッセージは何も発生していません。 JMSで何かをやったのでしばらく経ちましたが、システムの修正中にメッセージをデッドレターキューなどに送信したくないので、一度メッセージを元のキューに戻します再び処理する準備ができましたか
WebLogic では、最大再試行数、最大再試行制限を超えるメッセージを処理するためのエラー キュー、およびその他のパラメータを設定できます。はっきりとはわかりませんが、待機期間を指定することもできるかもしれません。これらはすべて管理コンソールで利用できます。あなたが所有している JMS プロバイダーの管理者を調べて、同様のことができるかどうかを確認します。
JBossでは、次のコードがトリックを実行します。
MBeanServer mbeanServer = MBeanServerLocator.locateJBoss();
ObjectName objName = new ObjectName("jboss.j2ee:ear=MessageGateway.ear,jar=MessageGateway-EJB.jar,name=MessageSenderMDB,service=EJB3");
JMSContainerInvokerMBean invoker = (JMSContainerInvokerMBean) MBeanProxy.get(JMSContainerInvokerMBean.class, objName, mbeanServer);
invoker.stop(); //Stop MDB
invoker.start(); //Start MDB
電話できると思います
messageConsumer.setMessageListener(null);
MessageListener実装内で、再確立タスクをスケジュールします(ScheduledExecutorServiceなど)。このタスクは呼び出す必要があります
connection.stop();
messageConsumer.setMessageListener(YOUR_NEW_LISTENER);
connection.start();
これは機能します。 start()およびstop()メソッドは、配信構造(TCP接続ではない)の再起動に使用されます。
Javadocを読む https:// docs .oracle.com / javaee / 7 / api / javax / jms / Connection.html#stop--
接続による着信メッセージの配信を一時的に停止します。接続の開始メソッドを使用して配信を再開できます。接続が停止すると、すべての接続のメッセージコンシューマへの配信が禁止されます。同期受信ブロック、およびメッセージはメッセージリスナに配信されません。
着信メッセージの接続の配信を一時的に停止するには、 Connection
インターフェースから stop()
メソッドを使用する必要があります: https://docs.oracle.com/javaee/7/api/javax/jms/Connection。 html#stop--
JMS仕様によると、 MessageListener
から connection.stop()
を呼び出さないでください。デッドロックまたは例外が発生します。代わりに、別のスレッドから connection.stop()
を呼び出すことができます。 MessageListener
と、関数 connection.stop()で接続を中断するスレッドを同期するだけです。