3

システム内の各ジョブは特定のユーザー ID に属しており、複数のソースから rabbitmq に配置できます。私の要件:

  • 任意の時点でユーザーごとに 1 つ以上のジョブを実行することはできません。
  • 特定のユーザーのジョブが積み重なって、他のユーザーのジョブが遅延することはありません。
  • 各ジョブは少なくとも 1 回実行する必要があります。各ジョブには最大再試行回数があり、失敗した場合は遅延してキューに再挿入 (またはおそらく遅延) されます。
  • ジョブの順序 (ユーザーごと) を維持することは望ましいことですが、必須ではありません。
  • ジョブは少なくとも 1 回実行する必要があるため、おそらく永続化する必要があります。ジョブの有効期限はありません。
  • どのワーカーも、どのユーザーに対してもジョブを実行できる必要があります。

これらの要件により、個々のユーザーごとに 1 つのキューを維持することは理にかなっていると思います。また、すべてのユーザー キューを監視し、ジョブが現在どこにも実行されていないユーザーのジョブを実行するすべてのワーカーが必要です (つまり、ユーザーごとに 1 つのジョブしかありません)。

このソリューションは、クラスター設定で RabbitMQ を使用して機能しますか? キューの数が多くなるため、すべてのユーザー キューを監視する各ワーカーが大きなオーバーヘッドを引き起こすかどうかはわかりません。どんな助けでも大歓迎です。

4

1 に答える 1

2

@dectarin が述べたように、複数のワーカーが複数のジョブ キューをリッスンすると、ユーザーごとに 1 つのジョブのみが実行されるようにすることが難しくなります。

ジョブがいくつかのステップを経ると、よりうまくいくと思います。

  1. ユーザーがジョブを送信
  2. 他のジョブが実行されなくなるまで、ジョブはユーザーごとにキューに入れられます
  3. コーディネーターは、ワーカーによって消費されるアクティブなジョブ キューにジョブを配置します
  4. ワーカーがジョブを取得して実行する
  5. ワーカーは結果キューに結果をポストします
  6. 結果はユーザーに送信されます

ジョブがシステムに送信される方法がわからないため、実際のユーザーごとの MessageQueue が待機中のキューに入れるのに最適な方法であるかどうかを判断するのは困難です。たとえば、ジョブが既にメールボックスにある場合、それも同様に機能する可能性があります。または、キューに入れられたジョブをデータベースに保存します。ボーナスとして、ユーザーがキューに入れられたジョブを検査および管理するための小さなフロントエンドを作成できるようになります。

選択内容に応じて、ユーザー制約ごとに 1 つのジョブを調整する洗練された方法を見つけることができます。

たとえば、ジョブがデータベースにある場合、データベースは物事の同期を維持し、複数のコーディネーター ワーカーが次のループを通過する可能性があります。

while( true ) {
    if incoming job present for any user {
        pick up first job from queue
        put job in database, marking it active if no other active job is present
        if job was marked active {
            put job on active job queue
        }
    }
    if result is present for any user {
        pick up first result from result queue
        send results to user
        mark job as done in database
        if this user has job waiting in database, mark it as active
        if job was marked active {
            put job on active job queue
        }
    }
}

または、待機中のジョブがユーザーごとのメッセージ キューにある場合、トランザクションはより簡単になり、ループを通過する単一のコーディネーターはマルチスレッドについて心配する必要がなくなります。

データベースとキュー全体で物事を完全にトランザクション化するのは難しいかもしれませんが、必ずしも必要ではありません。保留状態を導入することで、ステップが失敗した場合にジョブが失われないように注意を怠ることができます。

于 2014-08-08T11:50:09.767 に答える