2

每当有人 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);

基本上每次发送 PM 时,都会执行邮件功能,并在现场发送消息。因此,每发送 100 条消息,mail() 就会被调用 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);

我可以将此脚本设置为 cron 并让它每小时运行一次。所有的电子邮件都是一次性发送的,邮件功能只被调用一次。唯一的缺点是用户在收到 PM 时不会立即收到通知,而是在一小时内通知一次。但这没什么大不了的,我可以忍受。

我的问题是:

  • cron 方法在性能方面明显更好还是可以忽略不计
  • 这是大多数大型网站的做法吗?还是有更好的方法,一些已建立的图书馆可能会?

谢谢。

4

3 回答 3

1

您可以在 mysql 表中插入邮件(emailoutgoing)

并且每“3”分钟运行一次 cron 作业,您可以从表中收到未发送的(100 封?)电子邮件,发送并将行标记为已发送。

于 2012-04-18T20:11:31.983 回答
0

如果我理解正确,您会向每个人发送完全相同的电子邮件吗?在这种情况下,您应该为电子邮件地址使用密件抄送字段,否则每个人都会看到其他收件人,但在这种情况下,您可能会遇到反垃圾邮件引擎的问题,这些引擎可能会忽略您的电子邮件,因为他们不会将他们的用户视为电子邮件的收件人(不在在 to 或 cc 字段中)。

但是您真的应该考虑为每个用户发送个性化的电子邮件(如果您将 sneek preview 添加到谁发送了消息和/或消息的一部分,他们会更加渴望)

于 2012-04-18T22:29:07.257 回答
0

首先,阅读 Mike B 评论中的链接。

其次,您的代码有一些有趣的失败模式——它可能会失败,将所有邮件标记为已发送,而没有人会知道。关于 CRON 和其他无人值守进程(包括一般的网站)的一个关键问题是您需要知道何时出现问题。在您发送邮件后,我会考虑将“更新”声明放在最后。放入某种日志记录,以便您可以跟踪正在发生的事情。

第三,请不要将这封电子邮件发送给“收件人”字段中的所有这些人——正如米罗所说,这是垃圾邮件的诱饵,但它也会让用户接触到比他们应该拥有的更多的信息——他们知道随机其他人的电子邮件地址您网站的用户在一个小时内碰巧收到了 PM。如果你正在建立一个约会网站或社交网络,那几乎肯定会让人们生气。

最后,我工作过的其他有类似要求的站点往往有一个“事件”表,由守护进程/服务样式进程监控。守护进程会对做什么做出明智的决定。我们设计的解决方案适合在多线程甚至多台机器上运行,尽管实际上从来不需要这样。

因此,您可能有一个“事件”表,如下所示:

eventID    eventDate    eventType     eventStatus     eventMeta
-------------------------------------------------------------------
1          1 Feb 2012        PM           NEW         <from>bob@banana.com</from><to>alice@passionfruit.com</to>
2          1 Mar 2012        PM           COMPLETE    <from>fred@pear.com</from><to>jennifer@avocado.com</to> 

守护程序不断扫描 eventStatus 为 NEW 的记录,将它们设置为“进行中”,处理它们,然后将状态设置为完成。

这使您可以查看系统中正在发生的事情 - 如果记录“正在进行”超过一秒钟,则说明某些内容已损坏。如果“新”记录的数量不断增长,而“完整”记录的数量没有增长,那么就会出现问题。

于 2012-04-18T23:55:37.323 回答