2011-07-12 12 views
6

大量の電子メールを処理し、渡されたパラメータに従ってコンテンツを解析するための一括メール送信クラスを作成しました。私が1000のランダムな受信者と1000人のランダムな送信者の電子メールをデータベースから試してみると、スクリプトがsend()の部分に当たるまで(私は今コメントしています)、約2秒のパフォーマンスと20 MBのピークメモリこれは素晴らしいことです。PHP、sendmail、transports - メール送信を高速化する方法

ただし、送信部分のコメントを外すと、送信に30秒かかります。これは容認できないものです。私は何とかそれをスピードアップしたいと思います。テストから、$ mail-> send()以外の呼び出しによって遅延が発生していることは明らかです。ループを続行して次の電子メールを送信する前に何かを返すのを待っているかのようです。

私が思っているのは、send()コールをスピードアップするにはどうすればいいですか?それをより速くするために私は何ができますか?私は2つの送信方法を試しました。

  1. Zend SMTPトランスポート、サーバーに直接接続して送信するだけです。これには、電子メール1000件につき30秒かかります。
  2. Sendmail経由でZend_Mail。 Zend_Mailのsend関数は、各メールを準備した後で呼び出すだけです。これには60秒かかります。

キューイングは間違いなくオプションであり、クラスに組み込んでいます。それが必要なのはクーロンを活性化することであり、それは魅力のように機能します。しかし、私は実際の送信とそれをスピードアップする方法について不思議です。つまり、実際のsend()呼び出しです。

答えて

2

私は、ディレクトリ内のメールを保存し、シェルスクリプトを(cronを/デーモン/ ...)を使用してそれらを送信したい:私は間違いなくこのになります

Zend_Mail::setDefaultTransport(
    new Zend_Mail_Transport_File(
     array(
      'path' => __DIR__, 
      'callback' => function() { 
       do { 
        $file = 'email-' . date('Y-m-d_H-i-s') . '_' . mt_rand() . '.eml'; 
       } while (file_exists($file)); 
       return $file; 
      }, 
     ) 
    ) 
); 
+0

私が間違っている場合は私を修正してください。ただし、良いMySQLクエリは常にファイルの読み込みを上回ります。キューイングの仕組みは既にどちらの方法でも行われており、今は改善の必要はありません。同様に、私たちの電子メールはそれぞれ異なる内容を持っています。だから私たちは2秒で1000の電子メールを送信している間、それらのそれぞれは異なる受信者、異なる送信者と異なるコンテンツを持っています。私はあなたがここに表示されたこの側面は大量の電子メールでのみ役に立つと思う、はい?すべてのメッセージでコンテンツが同一の場合そうでない場合、質問はまだ残っています - これは、データベースのキューに入れるよりも速いでしょうか?私は懐疑的だ。 – Swader

+0

私は問題が発生していないと思った! :)いくつかの最適化されたメールサーバーがあり、メッセージのgazzilionsを大量に読み込むことができます。 Anycase - phpのsendmailよりも高速です。直接サーバーへのアクセスは、phpがこれまで以上に多くの時間を費やす必要があります(たとえば、永続的な接続を使用することができます)。 –

+0

うん、まあまあ。準備された電子メールはeml形式でディスクに簡単に保存でき、その後はスクリプトが引き継がれます。これは代替キューとしても有効です。効率的なやり方でこのような事例がありますか?私はいくつかを見てみたい。 – Swader

2

サーバー上のMTAを高速化する必要があります。私はPostfixをお勧めします。そしてあなたは実際に各設定を読み、それを微調整する方法を知っています。私はPowerMTAが良い選択だと聞きましたが、私はそれを試したことがありませんでした。

1台のマシンから抜き出すことができるほどのパフォーマンスはありますが、正規の専用サーバーでは、正常に設定したメールはかなり印象的です。パフォーマンス上のボトルネックは、通常、メールキューが格納されているディスクドライブであるため、SAS(10kまたは15k RPM)またはSSDドライブの使用を検討してください。

+0

。私たちの電子メール出力は非常にすぐに増加し、そのようなステップアップは非常に必要かもしれません。 – Swader

+0

このアプローチを計画し始めましたが、私たちのソリューションにはTomasの回答も含まれます。実際にはこれまで信じられないほど素晴らしいことが実証されています。 – Swader

0

PHP pcntl-forkの機能を掘り下げることができます。したがって、次の電子メールの解析中に、別のプロセスで送信を残すことができます。

PLAN Bのあなたがシリアライズおよびデータベースキューに電子メールオブジェクトを保存し、別のスクリプトをバックグラウンドでそれらを送信するためにさせることができます

。このスクリプトは無限ループ(while true)で実行され、すべての繰り返しでいくつかのsleepが実行されます。このスクリプトの複数のインスタンスを実行することもできますが、2つのスクリプトが同じ電子メールを同時に送信しないようにしてください。

スクリプトが実行中であることを確認するには、Unixマシンでmonitを使用できます。何らかの理由で古いインスタンスが失敗した場合、スクリプトを開始することができます。

+0

ええと、これは非常に魅力的ですが、PHPがApacheモジュールとして実行されている場合、PCNTL機能が利用できないという事実ではありませんか?私はどこかでそれについて何かを読んでいるように思いますが、それ以上情報を見つけることはできません。また、PCTNLは、Windowsマシン上で使用できない、と私は与えられた瞬間に午前ところによっては、OSのすべての種類で、このアプリを開発... – Swader

+0

は、平面B. – Gedrox

+0

を追加している私はすでにキューイングのこのタイプを使用しています。電子メールデータはシリアル化され、所定の優先順位でDBに保存されます。 cronjobは、15分ごとに500件の最優先メールを取り出すことで、定期的に送信を処理します。しかし、私が本当に望むのは、send()関数のスピードアップだけです。専用サーバーはおそらく唯一最良の長期的なソリューションに過ぎません。 – Swader

関連する問題