2011-07-12 22 views
6

我剛寫了一套批量郵件類,用於處理大量電子郵件並根據傳遞的參數解析其內容。如果我測試1000個隨機收件人和我的數據庫中的1000個隨機發件人的電子郵件,直到腳本點擊send()部分(我現在評論它),我的性能大約爲2秒,而峯值內存爲20 MB ,這很棒。PHP,sendmail和傳輸 - 如何加快郵件發送

但是,如果我取消註釋發送部分,則發送需要30秒。這是不可接受的,我想以某種方式加快速度。從測試中可以明顯看出,延遲是由$ mail-> send()調用引起的,就好像它正在等待它返回一些內容,然後繼續循環併發送下一封電子郵件。

我想知道的是:如何加快send()調用?我能做些什麼來使其更快?我試着使用兩種通知方法:

  1. Zend的SMTP傳輸,連接到服務器直接發送剛。這需要每1000封電子郵件30秒。
  2. Sendmail via Zend_Mail。準備好每封電子郵件後,只需調用Zend_Mail的發送功能。這需要60秒。

請注意,排隊絕對是一種選擇,我已經將它構建到我的課程中。它只需要激活一個cron,它就像一個魅力。但我想知道實際的發送和如何加快速度。所以,實際的send()調用。

回答

2

我會保存在郵件目錄和使用shell腳本(的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。任何情況 - 這將比PHP的sendmail方法更快。直接服務器訪問應該比php多出許多倍(例如,它可以使用持久連接)。 –

+0

嗯,很對。準備好的電子郵件可以很容易地以eml格式保存到磁盤中,然後從腳本開始接管。這也可以作爲替代隊列體面地服務。你有沒有以有效的方式完成這個任務的例子?我很想看看一些。 – Swader

2

您將需要加快服務器上的MTA。我推薦Postfix,並且你真的瞭解每個設置,所以你知道如何微調它。對於商業解決方案,我聽說PowerMTA是一個不錯的選擇,但我從來沒有嘗試過。

只有一臺機器可以擠出很多性能,但一旦您正確配置了正常的專用服務器,就應該能夠提供相當多的郵件。最大的性能瓶頸通常是存儲郵件隊列的磁盤驅動器,因此請考慮使用SAS(10k甚至15k RPM)或SSD驅動器。

+0

我一定會考慮這一點。我們的電子郵件輸出將會很快顯着增加,而這種提高可能是非常必要的。 – Swader

+0

我們已經開始規劃這種方法,但我們也會將Tomas的答案納入我們的解決方案。到目前爲止,它已經證明非常棒。 – Swader

0

您可以嘗試挖掘PHP pcntl-fork函數。因此,您可以在解析下一封電子郵件時將發送方留在另一個進程中。

B計劃

可序列化和保存的電子郵件對象到數據庫的隊列,並讓另一個腳本給他們的背景。此腳本可以在無限循環中運行(while true),每次迭代時都有一些sleep。您甚至可以運行此腳本的多個實例,但請確保兩個腳本不會同時開始發送相同的電子郵件。

爲確保腳本仍在運行,您可以在Unix機器上使用monit。如果舊的實例由於某種原因失敗,它能夠啓動腳本。

+0

嗯,這看起來非常有吸引力,但是如果PHP作爲Apache模塊運行,PCNTL函數不可用嗎?我似乎回想起在某處閱讀某些內容,但無法再找到這些信息。此外,PCTNL在Windows機器上不可用,並且我在各種操作系統上開發此應用程序,具體取決於我在給定時刻的位置。 – Swader

+0

已添加計劃B. – Gedrox

+0

我已經在使用這種類型的排隊。電子郵件數據被序列化並以給定的優先級保存到數據庫。然後cronjob每隔15分鐘定期處理髮送500條高優先級郵件的發送,而且它看起來都很好。但我真正想要的只是加速send()函數,而專用服務器可能僅僅是唯一且最好的長期解決方案。 – Swader

相關問題