2

WebSphereMQv7.1で入力キューをリッスンするSpringを使用してDefaultMessageListenderContainerSpringMDPを実装しました。悪いメッセージが入ってくると(それが原因でRuntimeException)、現在起こっていることは、トランザクションがロールバックされ、メッセージがキューに戻されることです。ただし、MDPは無限ループに入ります。

質問1:私の要件では、悪いメッセージが表示された瞬間に処理をシャットダウンできるようにしたいと思います。再試行は必要ありません。System.exit()(原油またはその種のメソッドとは対照的に)悪いメッセージが表示された場合にメッセージリスナーを正常にシャットダウンすることは可能ですか?私はそれが無限ループに入るのは絶対に好きではありません。

編集:

質問2:リスナーコンテナを停止または一時停止して、メッセージのそれ以上の処理を停止する方法はありますか?

4

3 に答える 3

2

これを処理する通常の方法は、エラーキューを作成し、不正なメッセージが表示された場合にそれをエラーキューに入れることです。
IBM MQシリーズなど、一部のシステムはこれを処理します。エラーキューと、必要な再試行回数を設定するだけで、エラーキューがそこに配置されます。
次に、管理者はこれらのキューを調べて、キューにあるメッセージに対して適切なアクションを実行します(つまり、メッセージを修正して再送信します)。

于 2012-03-12T17:58:23.567 に答える
1

実は、System.exit()残酷すぎて…うまくいきません。失敗したメッセージの再試行はブローカー(WMQ)側で処理されるため、アプリケーションを再起動するとメッセージが再配信されます。

あなたが説明している問題はと呼ばれ、ブローカー側で処理する必要があります。これは、WMQマニュアルの「ポイズン・メッセージの処理」およびWebSphere ApplicationServerがポイズン・メッセージを処理する方法で説明されているようです。

于 2012-03-12T17:58:39.397 に答える
0

私は次の方法で問題を解決しました。これが最善の方法かどうかはわかりませんが、機能します。

  1. MDPはApplicationContextAwareを実装します。また、リスナーの状態(OPEN、CLOSE、ERROR値の列挙型)を維持します。以下のMDPコードフラグメント:
//context
private ConfigurableApplicationContext applicationContext;

//listener state
private ListenerState listenerState = ListenerState.OPEN;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  this.applicationContext = (ConfigurableApplicationContext) applicationContext;
}
//onMessage method
public void processMessages(....) {
  try {
    process(...);
  } catch (Throwable t) {
    listenerState = ListenerState.ERROR;           
    throw new RuntimeException(...);            
  }    
}

@Override
public void stopContext() {        
  applicationContext.stop();  
}
  1. SpringコンテキストをロードするJavaメインでこれを行います:
    //check for errors for exit
    Listener listener = (Listener)context.getBean("listener");
    listenerContainer listenerContainer =
            (ListenerContainer)context.getBean("listenerContainer");

    try {
        while(true) {
            Thread.sleep(1000); //sleep for 1 sec
            if(!listener.getListenerState().equals(ListenerState.OPEN)) {
                listener.stopContext();
                listenerContainer.stop();
                System.exit(1);
            }>             }            
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
于 2012-03-16T15:41:33.580 に答える