0

私は、rabbitmq メッセージと Django アプリケーションの間にロギング ブリッジを構築して、バックグラウンド タスクの状態をデータベースに保存し、さらに調査/レビューできるようにしています。また、Django 管理インターフェイスを介してタスクを再発行できるようにしています。私はそれが派手なものではなく、単なる標準的な生産者と消費者のパターンだと思います。

  1. Web アプリケーションがメッセージ キューにパブリッシュし、初期タスク状態をデータベースに挿入する
  2. 別の Python プロセスであるコンシューマーは、メッセージを処理し、タスクの出力に応じてタスクの状態を更新します。

問題は、一部のタスクがデータベースにないため、実行されないことです。db commit が実行される前に Consumer がメッセージを受信したためだと思われます。したがって、基本的に Model.save() から戻ったからといって、トランザクションが終了して通信全体が中断したわけではありません。

これを修正する方法はありますか?たぶん、ある種の post_transaction シグナルを使用できますか?

前もって感謝します。

4

2 に答える 2

0

Webアプリケーションはメッセージキューに公開し、初期タスク状態をデータベースに挿入します

こんなことしないで。

Webアプリケーションはキューに公開します。終わり。テンプレートを介して結果を提示し、Webトランザクションを終了します。

コンシューマーはキューからフェッチして処理を実行します。たとえば、ユーザーに表示するためにデータベースのログに追加する場合があります。コンシューマーは、実行時にデータベースに追加のステータスを投稿することもできます。

実際、多くのアプリケーションには、複数の生産者/消費者の関係を持つ複数のキューがあります。各プロセスは、ログに物事を追加する場合があります。

次に、プレゼンテーションでログエントリを要約する必要があります。多くの場合、最後のもので十分な要約ですが、以前のエントリからのカウントまたは情報が必要な場合もあります。

于 2010-06-14T10:16:28.503 に答える
0

これは私にはもろく聞こえます。キューに投稿してから初期状態をデータベースに挿入する Web アプリがあります。Web アプリが初期状態をコミットする前に、コンシューマーがメッセージを処理するとどうなりますか?

DB がコンシューマーによってロックされているときに、Web アプリが新しい状態を挿入しようとするとどうなりますか?

これを修正するには、Web アプリで初期状態をメッセージに追加し、コンシューマーだけが DB に書き込む必要があります。

[編集] また、ロギングに問題がある可能性もあります。DB を変更せずにメッセージをキューに入れることによって、Web アプリとコンシューマーの間の競合がログに適切なエラーを生成することを確認します。

[EDIT2] いくつかのアイデア:

保留中のタスクの数だけを表示するのはどうですか? このために、Web アプリがテーブル 1 に書き込み、コンシューマーがテーブル 2 に書き込み、管理者が違いを示す場合。

コンシューマーがキューに持っている保留中のタスクを Web アプリが表示できないのはなぜですか? たぶん、 2 つのコンシューマーが必要です。最初のコンシューマーはタスクを DB に追加し、コミットしてから、新しい行の主キーのみを使用して 2 番目のコンシューマーにメッセージを送信します。管理者の iface は、2 番目のコンシューマがテーブルに書き込んでいる間にテーブルを読み取ることができます。

最後のアイデア: メッセージをエンキューする前にトランザクションをコミットします。このためには、単に「コミット」をデータベースに送信する必要があります。奇妙に感じるでしょう (どのような場合にもお勧めしません) が、ここでは、新しい行を手動でコミットすることが理にかなっています (つまり、通常のトランザクション ロジックを処理するフレームワークに戻る前に)。

于 2010-06-14T09:13:34.910 に答える