1

メッセージの処理中に 2 つの異なるタイプの問題を処理しようとしています。

最初の問題は、リモート データベースがダウンしている場合です。その場合、メッセージは処理を停止し、後で再試行する必要があります。このメッセージは決して DLQ に送られるべきではなく、リモート データベースが稼働するまで試行を続ける必要があります。

2 番目の問題は、メッセージに問題がある場合です。その場合は、DLQ に送信する必要があります。

次のコードをどのように構成すればよいですか?

@Override
public void onMessage(Message message) {
    try {

    // Do some processing
    messageProcessing(message);  // Should DLQ if message is bad

    // Save to the database
    putNamedLocation(message);  // <<--- Exception when external DB is down

    } catch (Exception e) {
        logger.error(e.getMessage());
        mdc.setRollbackOnly();
    }
}
4

1 に答える 1

0

MDB のコード本体で確実に不良メッセージを検出できると仮定すると、不良メッセージを直接 DLQ に書き込みます。これにより、おそらくエラーを分類したり、オプションでさまざまな種類の不良メッセージをさまざまな「DLQ ライク」キューに送信したり、DLQ されたメッセージに存続時間を適用したりする自由が少し増えます。常に処理されるタイプのメッセージは、いつまでもキューに積み上げられることはありません。ConnectionFactory および Queue 参照を参照する @Resource アノテーション付きインスタンス変数を MDB クラスに追加して、ターゲット DLQ へのメッセージの送信をサポートできます。肝心なのは、エラーを検出し、自分でメッセージを DLQ することです。

DB がダウンしている場合は、接続の取得時または更新の書き込み時に例外をキャッチすることでこれを検出できます。この場合、リソースをクリーンアップして、RuntimeException をスローします。これにより、メッセージが再配信されますが、次の 2 つの点について JMS 構成を確認する必要があります。

  1. max-redelivery カウントが十分に大きいことを確認してください。そうしないと、カウントがオーバーし、最終的にメッセージが DLQ されます。
  2. JMS 実装がサポートしている場合は、拒否されたメッセージに再配信遅延を追加して、DB が復旧するまでの時間を確保してください。そうしないと、メッセージが配信/拒否ループで際限なくスピンします。

#2 (JMS 実装が WebSphereMQ などの再配布遅延をサポートしていない場合は注意が必要です) を回避するには、MDB の JBoss JMX 管理インターフェースを使用して、MDB での配信を停止 (および後で再起動) します。ただし、MDB はメッセージの処理が完了するまで待機するため、メッセージを処理している同じスレッドの MDB 内でこれを行うことはできません。 't なぜなら...[など]だから...あなたの最善の策は、DBをポーリングし、それがダウンしていることが判明したときにMDBを停止し、再びそれが見つかったときにそれを再起動する、ある種の歩哨を開始することです。その方法のスニペットについては、この質問を参照してください。

その最後の部分は、メッセージの検証に起因する予期しない例外に対処するのに役立ちます。(つまり、DB は問題ありませんが、何らかの理由でメッセージが完全におかしいので、例外がキャッチされず、メッセージが再配信されます)。ダウン DB メッセージは (見張りのために) 数回以上再配信されるべきではないため、メッセージの再配信回数を確認できます。再配信回数がとてつもなく多い場合は、有害なメッセージがあることがわかり、それを破棄するか、DLQ を実行できます。それ。

お役に立てば幸いです。

于 2013-05-02T20:57:52.387 に答える