私は現在システムを再設計しており、ちょっとした問題に遭遇しました。
要件
メッセージのキュー ( RabbitMQキュー) と、そのキューから消費する多数のサービスがあります。各メッセージには、グループの一部であることを示す ID と、順序を示すのに役立つタイムスタンプがあります。
キューから消費する各サービスは、少なくとも 1 つのグループの処理を担当しますが、多数のグループを処理することもできます。サービスは複数のサーバーで実行できます。
システムは、可変数の消費サービスと、サービスの初期化/破棄時に ID が自動的に再割り当てされることを許可する必要があります。
メッセージはリアルタイムで処理する必要があり、バッファリングは許可されていません。メッセージは、ID グループ内で順番に処理する必要があります。
問題点・制約事項
Rabbit では、フェッチする前にキューをトラバーサルしたり、パターンに基づいて単一のキューからフェッチしたりすることはできません。
メッセージでは順序が重要です。単純に上位のメッセージを取得して、ID と一致しない場合は拒否できますが、これにより問題が発生します。
順序どおりの処理を強制するには、プリフェッチ カウント値を 1 に設定する必要があります。ただし、これにより、サービスが常にキューの先頭を取得しているにもかかわらず、どのサービスもメッセージを取得できないというライブロックが発生する可能性があります。プロセス、またはパフォーマンスに大きな影響を与えることはめったにありません。
逆に、これを合理的に軽減するのに十分な数にプリフェッチ カウントを設定すると、順不同の処理が可能になります。
いずれの場合も、プリフェッチ カウントを低い値に設定すると、パフォーマンスに大きな影響を与えるようです。
可能な解決策
複数のラビット キュー
コンシューマーごとにウサギのキューを自動的に生成し、トピック交換を使用してメッセージを自動的にルーティングすることは、可能な解決策のようです。
ただし、そのサービスのキューを処理する前に、消費するサービスの数を減らす必要がある場合、メッセージが失われるという問題が発生します。また、サービスが停止し、代替サービスを再開できない場合、メッセージが失われます。
コーディネーター/ワーカー
私の現在の考えは、キューから読み取り、ID に基づいてワーカーにメッセージを配布するコーディネーター サービスを用意することです。
これにより単一障害点が発生しますが、複数のコーディネーター プロセスを作成して、指定された ID をどのワーカーが担当するかをZookeeper経由で伝えることができます。
これには、次のいずれかのパターンが必要です。
- プッシュ:各コーディネーターは、すべてのワーカーのリストを維持し、メッセージが入ってくるとプッシュします。
- グローバル プル:各ワーカーはメッセージのすべてのコーディネーターをポーリングし、それらをローカルで並べ替えて処理します。
- ローカル プル:ワーカーは 1 つのコーディネーターへの接続を維持し、コーディネーターはコーディネーター間でメッセージをやり取りします。
質問
- マスター/ワーカー モデルは、この問題に対する実行可能な解決策ですか? そしてそうならば;
- コーディネーターはサーバー間でワーカーとどのように通信できますか? (上記の複数のウサギのキューの問題を回避しながら)
- 同様に、前述のローカル プル方式を使用する場合、コーディネーターは相互にメッセージをやり取りできます。
- 私が見落としている他の解決策はありますか?
どんな助けでも大歓迎です