web-dev-qa-db-ja.com

Python / Djangoとメッセージキューに関するアドバイス

Djangoにアプリケーションがあり、さまざまなユースケースでユーザーに多数のメールを送信する必要があります。明らかな理由から、これをアプリケーション内で同期的に処理したくありません。

Pythonとうまく統合できるメッセージキューサーバーに関する推奨事項はありますか、またはDjangoプロジェクトで使用していますか?残りのスタックはApache、mod_python、MySQLです。

42
Andy Hume

これまでのところ、これに対する「良い」解決策は見つかりませんでした。私にはもっと厳しいソフトリアルタイム要件があります(ラベルが貼られている段ボール箱から写真を撮る)ので、おそらくアプローチの1つはあなたにとって十分に速いです。メールは数分待つことができると思います。

  • Cronジョブによって処理されるデータベース内の「todoリスト」。
  • データベース内の「todoリスト」は、デーモンによってポーリングされたビーイングを永続的に処理しました。
  • UDPパケットを介してWebサーバーから通知を受けるカスタムデーモンを使用する(本番環境で)。基本的に、キューを処理するためのIPスタックを備えた私自身のキューイングシステム。
  • ActiveMQをメッセージブローカーとして使用 -安定性の問題のため、これは機能しませんでした。私にとってもJavaデーモンは一般的にややふっくらしています
  • CouchDBでの更新トリガーの使用。素晴らしいですが、更新トリガーは重い画像処理を行うことを意図していないので、私の問題には適していません。

これまでのところ、問題を処理するためにRabbitMQとXMPP/ejabebrdを試したことはありませんが、次に試すことのリストにあります。 RabbitMQは2008年にまともなPython接続を取得し、XMPPライブラリがたくさんあります。

しかし、おそらく必要なのは、ローカルマシン上で正しく構成されたメールサーバーだけです。これにより、メールをローカルメールサーバーに同期的にダンプできるため、ソフトウェアスタック全体がはるかに簡単になります。

14
max

あなたの特定のケースでは、それが単なる電子メールキューである場合、私は簡単な方法を取り、 Django-mailer を使用します。ニースの副産物として、Django-mailerをスタックで見たときにそれを利用するのに十分賢い他のプラグ可能なプロジェクトがあります。

より一般的なキューソリューションについては、まだこれらのいずれも試すことができませんが、私にとってより興味深いと思われるソリューションのリストを次に示します。

  1. pybeanstalk/beanstalkd
  2. gearmanへのpythonインターフェース (これはおそらく、 GearmanのCバージョン のリリースではるかに興味深いものになります)
  3. memcacheQ
  4. ストンプ
  5. セロリ
24
Van Gale

Stompserverは良いオプションです。軽量で、インストールが簡単で、Django/pythonから簡単に使用できます。

電子メールの送信や他のジョブの非同期処理のために、本番環境でstompserverを使用するシステムがあります。

Djangoはメールをデータベースに保存します。Djangoのmodel.post_saveハンドラーはイベントをstompserverに送信し、stompserverはそのイベントを非同期タスクを実行するコンシューマープロセスに渡します(メールを送信します)。

実行時にコンシューマープロセスを追加できるため、非常にうまくスケールアップします。2人のコンシューマーが2倍の数の電子メールを送信でき、コンシューマーは別々のマシンにいることができます。少し複雑なのは、各コンシューマーが独自の名前付きキューを必要とするため、Djangoは、使用可能なコンシューマーの数を認識し、ラウンドロビン方式で各キューにイベントを送信する必要があることです(2人のコンシューマーが同じキューが両方とも各メッセージを取得します=重複)。1つのコンシューマープロセスのみが必要な場合、これは問題ではありません。

以前は、ジョブについてデータベースを継続的にポーリングするプロセスがありましたが、何も処理する必要がない場合でも、システムに多くの負荷がかかることがわかりました。

6
Gruff

pymq をご覧ください。 Pythonで記述されており、クライアントとHTTPを通信し、キューの監視および管理オプションのホストを許可します。

1
dhruvbird

メールインフラストラクチャを使用してこれを解決することに何か問題がありますか?同様に、ローカルに送信されたメールをキューに入れる独自のメールデーモンを実行しているすべてのアプリサーバーは、メールを大量に処理できる集中型メールサーバーに転送しますか?

1

電子メールをデータベースに追加してから、タスクスケジューラユーティリティ(cronが思い浮かびます)によって実行される別のスクリプトを記述して、電子メールを送信します。

1
nosklo

http://www.snakemq.net/ も機能する可能性があります

1
David

これは怠惰ですが正しくて適切な解決策です。次のデータベーステーブルをキューとして使用します。

drop table if exists mailqueue;
create table mailqueue (
    id bigint primary key,
    subject text not null,
    body mediumtext not null,
    from varchar(255) not null,
    to varchar(255) not null
);

送信者は、このテーブルの最後に新しい行を挿入する必要があります。

もう一方の端(最小ID)から一度に1つずつメールをポップするようにワーカースレッドを設定し、それらを送信しようとします。

0
Seun Osewa

MySQLがすでにインストールされている場合は、ある種の「ToDoリスト」として使用するテーブルを作成できます。

スレッドは同期的にジョブをテーブルに追加し、バッチタスクはジョブが完了するとジョブを削除します。

そうすれば、ソフトウェアをインストールして学習する必要がなく、lotsを送信しない限り、永続的なジョブストアとして正常に機能するはずです。電子メールの(> 10 /秒など)。

0
James Brady