2012-04-18 44 views
2

我的網站每當有人發短信(私信)時,都會向我的用戶發送一封電子郵件。它表示的內容是「有人在站點名稱上向您發送了一條消息,請登錄查看」。什麼是通過PHP向大量用戶發送電子郵件的最有效方式?

此刻我的網站是不是很受歡迎,所以我現在這樣的方式一直沒有問題的表現明智的:

發送一個PM
// code that sends pm here... 

    // code that stores pm in messages table here... 

    // notify user by emailing them right away 
    mail($user_email, $subject, $message); 

基本上每次執行郵件功能並在當場發送信息。因此,每發送100封郵件,郵件()就會被調用100次。

我期待我的網站越來越受歡迎,並且隨着更多的用戶來到更多的PM,所以我認爲我目前的做法會成爲一場性能噩夢。所以我在想這樣做,而不是這樣的:

// get the last message that was accounted for by the last cron 
$query = mysql_query(" SELECT `last_checked_id` FROM `settings` "); 
$last_checked_id = mysql_fetch_array($query); 


$user_emails = array(); 

// get all messages that were added to this table since the last time this cron ran 
$query = mysql_query(" SELECT `recipient_id`, `message_id` FROM `messages` WHERE `message_id` > '$last_checked_id' "); 

$i = 0; 
while($row = mysql_fetch_array($query)) { 

    if($i == 0) { 
     // set this as the last message processed 
     mysql_query(" UPDATE `settings` WHERE `last_checked_id` = '". $row['message_id'] ."' "); 
    } 

    // only put this user in the to email list if he hasn't been added already (since there can be multiple messages for the same user but we need to notify him only once) 
    if(!in_array($row['recipient_id'], $user_emails)) { 
     array_push($user_emails, $row['recipient_id']);  
    } 
} 
$i++; 

// send email to all users at one 
mail(implode(',', $user_emails), $subject, $message); 

我可以將這個腳本爲計劃並運行它每隔一小時。所有的電子郵件都是一次發送的,郵件功能只被調用一次。唯一的缺點是用戶在他們收到PM時不會立即通知,而是在一小時內收到通知。但這並不是什麼大事,我可以忍受。

我的問題是:

  • 是cron的方法顯著更好的性能明智或增加微不足道
  • 這是多數大網站做到這一點?還是有更好的方法,一些已建立的圖書館可能會再見?

謝謝。從表

+1

關於SO最低調的PHP問題可能有一些見解http://stackoverflow.com/questions/3905734/how-to-send-100-000-emails-weekly – 2012-04-18 20:11:06

+1

相關:我也會限制一些電子郵件(如線程回覆通知),以便他們不會突然收到10封電子郵件,並告訴他們同一個線索已被評論。 – Xeoncross 2012-04-18 20:11:21

回答

1

您可以將郵件一個MySQL表(emailoutgoing)

而且隨着運行的每一個「3」分鐘cron作業,就可以得到未發送(100?)的電子郵件,發送和標記行作爲發送。

0

如果我理解正確,你會發送完全相同的電子郵件給每個人?在這種情況下,您應該爲電子郵件地址使用密件抄送字段,否則每個人都會看到其他收件人,但在這種情況下,您可能會遇到可能會忽略電子郵件的反垃圾郵件引擎問題,因爲他們不會將其用戶視爲電子郵件的收件人in或cc字段)。

但你真的應該想想發送個性化的電子郵件爲每個用戶

+0

我同意,實際上現在我發送了一封個性化的電子郵件,其中收到了他們收到的消息的預覽以及一個鏈接,以查看更多回到我的網站。我只是很快把這個例子搞砸了,如果我還想發送預告,我必須展開腳本。所有用戶都可以看到其他用戶的好處。我不知道mail()函數是這樣做的。 – TK123 2012-04-18 23:56:24

0

首先,閱讀鏈接(如果您添加斯內克預覽到誰發送的消息和/或消息的一部分,他們會更渴望)在Mike B的評論中。其次,你的代碼有一些有趣的失敗模式 - 它可能會失敗,將所有郵件標記爲已發送,並且沒人會知道。關於CRON和其他無人值守流程(包括一般網站)的一個關鍵問題是,您需要知道什麼時候出現問題。在發送郵件後,我會考慮在最後加上「更新」聲明。放入某種日誌記錄,以便跟蹤發生的情況。第三,請不要將此電子郵件發送給「to」字段中的所有這些人 - 正如Miro所言,它是垃圾郵件誘餌,但它也向用戶提供了比他們應該有的更多信息 - 他們知道電子郵件您的網站隨機其他用戶的地址,他們在一個小時內碰巧遇到了PM。如果你正在建立一個交友網站或社交網絡,那幾乎肯定會讓人生氣。

最後,我曾參與過的其他有相似要求的網站往往有一個「事件」表,這個表由守護進程/服務風格進程監視。守護進程會做出明智的決定。我們設計的解決方案適合在多個線程甚至多個機器上運行,但實際上從來不需要這個。

eventID eventDate eventType  eventStatus  eventMeta 
------------------------------------------------------------------- 
1   1 Feb 2012  PM   NEW   <from>[email protected]</from><to>[email protected]</to> 
2   1 Mar 2012  PM   COMPLETE <from>[email protected]</from><to>[email protected]</to> 

的守護進程不斷掃描記錄,其中eventStatus是新的,將它們設置爲「中」,與他們交易,然後設置:

所以,如下你可能有一個「事件」表狀態完成。

這使您可以查看系統中正在發生的事情 - 如果某個記錄正在「進行中」超過一秒鐘,則某些內容已損壞。如果「新」記錄的數量持續增長,並且「完整」記錄的數量沒有增加,則某些內容被打破。

相關問題