Django にアプリケーションがあり、さまざまなユースケースで多数の電子メールをユーザーに送信する必要があります。明らかな理由から、アプリケーション内でこれを同期的に処理したくありません。
Python とうまく統合できるメッセージ キューイング サーバーの推奨事項はありますか、または Django プロジェクトで使用したことがありますか? 私のスタックの残りは、Apache、mod_python、MySQL です。
Django にアプリケーションがあり、さまざまなユースケースで多数の電子メールをユーザーに送信する必要があります。明らかな理由から、アプリケーション内でこれを同期的に処理したくありません。
Python とうまく統合できるメッセージ キューイング サーバーの推奨事項はありますか、または Django プロジェクトで使用したことがありますか? 私のスタックの残りは、Apache、mod_python、MySQL です。
それが単なるメールキューである特定のケースでは、簡単な方法でdjango-mailerを使用します。良い副次的なボーナスとして、django-mailer がスタックに表示されたときにそれを利用するのに十分スマートなプラグ可能なプロジェクトが他にもあります。
より一般的なキュー ソリューションについては、まだこれらのいずれも試すことができませんでしたが、より興味深いもののリストを次に示します。
これまでのところ、これに対する「良い」解決策は見つかりませんでした。より厳密なソフト リアルタイム要件 (ラベルが付けられた段ボール箱から写真を撮る) があるので、おそらくアプローチの 1 つが十分に高速です。メールは数分待つことができると思います。
これまでのところ、この問題を処理するために RabbitMQ と XMPP/ejabebrd を試していませんが、次に試すリストには入っています。RabbitMQ は 2008 年に適切な Python 接続を取得し、多数の XMPP ライブラリが存在します。
しかし、おそらく必要なのは、ローカル マシン上に正しく構成されたメール サーバーだけです。これにより、メールを同期的にローカル メールサーバーにダンプできるようになり、ソフトウェア スタック全体がよりシンプルになります。
Stompserver は良いオプションです。軽量で、インストールが簡単で、Django/python から簡単に使用できます。
電子メールを送信し、他のジョブを非同期に処理するために、本番環境で stompserver を使用するシステムがあります。
Django はメールをデータベースに保存し、Django の model.post_save ハンドラーはイベントを stompserver に送信し、stompserver は非同期タスクを実行する (メールを送信する) コンシューマー プロセスにイベントを渡します。
実行時にコンシューマー プロセスを追加できるため、非常にうまくスケールアップします。2 人のコンシューマーは 2 倍の電子メールを送信でき、コンシューマーは別のマシンに配置できます。少し複雑な点として、各コンシューマーには独自の名前付きキューが必要なため、Django は利用可能なコンシューマーの数を把握し、ラウンドロビン方式で各キューにイベントを送信する必要があります。(同じキューでリッスンしている 2 つのコンシューマーは、両方とも各メッセージを取得します = 重複)。コンシューマ プロセスが 1 つだけ必要な場合、これは問題になりません。
以前は、ジョブを求めてデータベースを継続的にポーリングするプロセスがありましたが、何も処理する必要がない場合でも、システムに多くの負荷がかかっていることがわかりました。
メールインフラストラクチャを使用してこれを解決するのに何か問題はありますか? 同様に、ローカルで送信されたメールをキューに入れる独自のメール デーモンを実行しているすべてのアプリ サーバーは、メールの重労働を処理できる中央のメール サーバーに転送されますか?
電子メールをデータベースに追加し、タスク スケジューラ ユーティリティ (cron が思い浮かびます) によって実行される別のスクリプトを記述して、電子メールを送信します。
pymqを見たいと思うかもしれません。これは Python で書かれており、クライアントと HTTP でやり取りし、キューの監視および管理オプションのホストを許可します。
これは怠惰ですが、正しく適切な解決策です。次のデータベース テーブルをキューとして使用します。
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 つずつメールをポップし、送信を試みます。
すでに MySQL がインストールされている場合は、ある種の「todo リスト」として使用するテーブルを作成できます。
スレッドは同期的にテーブルにジョブを追加し、バッチ タスクは完了時にジョブを削除します。
そうすれば、ソフトウェアをインストールして学習する必要はなく、大量の電子メールを送信しない限り (1 秒あたり 10 件以上)、永続的なジョブ ストアとして正常に機能するはずです。