1

JMS 永続トピックからメッセージを読み取り、処理のためにスレッドプールに送信するスタンドアロンの Java プロセスがあります。明らかな並行性の理由からこのようにしていますが、これらのメッセージの処理順序を維持し、それらを単一のスレッド プールに送信しています。ここで、JVM クラッシュに関する私の懸念事項を説明します。

-- 非トランザクション
トランザクション コンテキストですべてのメッセージを読み取って処理しているわけではありません。プロセスが遅くなるので避けました。そのため、スレッドプールのブロッキング キューにメッセージを蓄積しています。しかし、たとえば 10 個のメッセージが処理待ちのスレッドプールにあるときに JVM がクラッシュすると、そのデータが失われます。

--
トランザクション トランザクション内の各メッセージを読み取って処理すると、何か問題が発生した場合、そのメッセージはバックアップ時にプロセスに再配信されると思います。

これは、低遅延システムで作業している多くの人々に共通の問題であるため、経験豊富な人々がこの問題にどのように取り組んでいるのか疑問に思っていますか? ありがとう。

4

1 に答える 1

2

ピーターの知る限り正しいです。これを回避する 1 つの方法は、パターンが適用できる場合、何らかの境界を使用して、メッセージをグループ化するためのさまざまなキューを作成することです。つまり、この要件は、「1 つのアカウントのすべてのメッセージを順番に処理する必要がある」などの意味に分解されることがよくあります。したがって、これに似たものがあれば、次のいずれかを作成できます。

  • 1 つのトピックと複数のサブスクライバーがあり、それぞれが排他的なセレクター (またはサブトピック パターン) を使用している
  • それぞれが単一のサブスクライバーを持つ複数のトピック。

次に、サイト運営者は次のことを決定する必要があります。

  • パブリッシュされたメッセージのヘッダーにより、正しいセレクターがサブスクライバーに対して有効になります。または
  • 公開する正しいサブトピック、または
  • 公開する正しいトピック

これを行うための簡単に維持できるパターンは、ビジネス フィールドの 1 つ (アカウント番号など) を使用してmod(x)を計算することです。ここでxは、作業負荷を共有するために必要なサブスクライバーの数です。ビジネス キーが数値であり、適切な分布が得られることを願っていますが、キーを逆にしたり、数値以外の値をハッシュしたりすることで、他の決定論的アルゴリズムをいつでも使用してこの数値を生成できます。

余談ですが、あなたのアウトラインには、Pub-Sub/JMS トピックではなく、Point-to-Point/JMS Queue の雰囲気がかなりあります。トピックを使用してもよろしいですか?

データを絶対に失うことができない場合は、トランザクション メッセージを使用する必要があります。トランザクション メッセージを使用する場合は、スレッド プールに委譲できません。JMS メッセージのトランザクション コンテキスト (セッション) は、メッセージが受信されるスレッドにバインドされるため、このコンテキストを別のスレッドに転送する「面白いビジネス」を有効にしない限り.....

その文をどのように終わらせればよいかさえわかりません。

====更新====

考えてみると、メッセージの処理を並列化することでメリットが得られる場合は、メッセージのバッチをすべて 1 つのトランザクション内で取得し、それらすべてをExecutorService.invokeAll呼び出しに委譲し、完了を待ってトランザクションをコミットすることができます。すべて完了しています。invokeAll がタイムアウトした場合、またはタスクの 1 つが例外をスローした場合は、トランザクションをロールバックするか、何らかの補償アクションを実行する必要があります。

于 2013-02-04T19:55:16.630 に答える