15

私は、マルチテナント クラウド ベースのアプリケーションである Web アプリケーション (多数のクライアント、それぞれが独自の「環境」を持っていますが、すべてがハードウェアの共有セット上にある) で作業しており、ユーザーがバッチ処理を行う機能を導入しています。後の処理に使用します。バッチ化された作業の種類は実際には重要ではありません。作業キューなしでそれを行うのは実際には実用的ではないほど十分な量です。基盤となるキュー フレームワークとして RabbitMQ を選択しました。

私たちはマルチテナント アプリであるため、クライアントが別のクライアントに対して長いキュー処理時間を引き起こすことを必ずしも望んでいるわけではありません。すべてのクライアント キューを指す共有ワーカー プール。問題は、私が把握できる限り、ワーカーは交換ではなく、特定のキューに直接バインドされていることです。私たちの理想的な世界では、クライアント キューは、1 つのクライアントが別のクライアントをブロックすることなく、必要に応じてより多くのワーカーを起動したり、アイドル状態のワーカーを閉じたりすることで拡大または縮小できる共有ワーカー プールから処理されます。特定のキューに関連付けられたワーカーを持つことで、多くのワーカーがアクティビティのないキューでアイドル状態になっていることが多いため、実際的な意味でこれを防ぐことができます。

これを達成するための比較的簡単な方法はありますか? 私はRabbitMQにかなり慣れていないので、私たちが求めていることを実際に達成できていません. また、非常に複雑なマルチスレッドの消費者向けアプリケーションを作成する必要もありません。これは、開発とテストの時間の浪費であり、余裕がない可能性があります。私たちのスタックは Windows/.Net/C# ベースです。

4

4 に答える 4

5

プライオリティ キューの実装を見ることができます (この質問が最初に尋ねられたときには実装されていませんでした): https://www.rabbitmq.com/priority.html

それがうまくいかない場合は、他のハックを試して目的を達成することができます (RabbitMQ の古いバージョンで動作するはずです)。

トピック交換に 100 個のキューをバインドし、ルーティング キーをユーザー ID % 100 のハッシュに設定することができます。つまり、各タスクには 1 から 100 までのキーがあり、同じユーザーのタスクには同じキーがあります。各キューは 1 から 100 までの一意のパターンでバインドされています。これで、ランダムなキュー番号で始まり、各ジョブの後にそのキュー番号をインクリメントするワーカーのフリートができました。キュー 100 の後にキュー 1 に戻るには、再び % 100 です。

これで、ワーカー フリートは最大 100 の一意のユーザーを並行して処理できます。または、他に行う作業がない場合は、すべてのワーカーが 1 人のユーザーに集中できます。ワーカーが各ジョブ間で 100 個のキューすべてを循環する必要がある場合、1 人のユーザーだけが 1 つのキューに多くのジョブを持っているというシナリオでは、当然、各ジョブ間にいくらかのオーバーヘッドが発生します。これに対処する 1 つの方法は、キューの数を減らすことです。また、各ワーカーが各キューへの接続を保持し、それぞれから最大 1 つの未確認メッセージを消費することもできます。ワーカーは、未確認メッセージのタイムアウトが十分に高く設定されていれば、メモリ内の保留中のメッセージをより高速に循環できます。

または、バインドされたキューを持つ 2 つの交換を作成することもできます。すべての作業は、ワーカーのプールが消費する最初の交換とキューに送られます。作業単位に時間がかかりすぎる場合、ワーカーはそれをキャンセルして 2 番目のキューにプッシュできます。ワーカーは、最初のキューに何もない場合にのみ 2 番目のキューを処理します。また、ユーザー バッチが常に最終的に処理されるように、キューの優先順位が逆の 2 つのワーカーが必要になる場合もあります。これにより、ワーカー フリートがすべてのタスクに真に分散されるわけではありませんが、あるユーザーからの長時間実行タスクが停止し、ワーカーが同じユーザーまたは別のユーザーの短時間実行タスクを実行できなくなります。また、ジョブをキャンセルして後で問題なく再実行できることも前提としています。また、タイムアウトしたタスクから無駄なリソースが発生し、優先度を低くして再実行する必要があることも意味します。速いタスクと遅いタスクを事前に識別できない限り

1 人のユーザーに 100 個の遅いタスクがあり、別のユーザーがタスクのバッチを投稿した場合、100 個のキューを使用した最初の提案でも問題が発生する可能性があります。これらのタスクは、遅いタスクの 1 つが完了するまで見られません。これが正当な問題であることが判明した場合は、2 つのソリューションを組み合わせることができます。

于 2016-09-27T22:45:49.150 に答える
1

RabbitMQ の仮想ホストを使用せず、アプリを RabbitMQ にログインさせ、ユーザーごとに個別の接続で認証する理由がわかりません。

これは、ワーカーをあるユーザーまたは別のユーザーに割り当てるワーカー スーパーバイザーを使用できないという意味ではありません。ただし、各ユーザーのすべてのメッセージが完全に個別の交換とキューによって処理されることを意味します。

于 2012-01-29T06:34:35.617 に答える
1

ワーカーのプールがすべて同じ一意のキューを消費するようにすることができます。その後、作業はそれら全体に分散され、作業処理能力を増減するためにプールを拡大/縮小できます。

于 2011-11-28T20:36:46.690 に答える