如何安排发送电子邮件

时间:2010-04-03 15:27:25

标签: php message-queue

使用PHP,我有一个查询,通过我的数据库在一天中的某些时间查找具有提醒触发器的待处理任务。我有一个每10分钟运行一次的cronjob,并检查数据库中是否有“remind_me”字段设置为在接下来的10分钟内关闭的任何行。如果确实找到了什么,那么使用任务信息排队电子邮件的最佳方法是什么?

我想我需要某种消息队列系统,但电子邮件部分如何工作?我是否需要另一个每分钟运行一次的cronjob来检查队列系统?

5 个答案:

答案 0 :(得分:3)

我最近刚刚使用PHP和MySQL编写了一个非常类似问题的解决方案 基本上:cron作业以设定的间隔运行脚本,该脚本检查数据库是否有待处理的作业,运行它们并删除作业。

这正是我需要做的事情,但可以修改它以适应时间间隔 我编写了一个单独的PHP脚本来运行实际的工作(新闻通讯系统),使这种自动化更有用。也就是说,我可以运行我想要的任何命令,我通过在automator脚本中存储实际命令的名称及其参数来实现这一点。

exec("~/scripts/{$row['command']} {$row['args']}");

允许我将参数存储到数据库中,以使我的新闻稿脚本更有用。您使用数组$ argv来获取参数,$ argv [0]是参数遵循的脚本名称。

我将所有简报信息存储在数据库中的单独表格中,该表格按时间顺序对它们进行排序。其他重要的字段是电子邮件的主题和正文。然后我简单地将两个参数传递给newsletter.php,使其完全符合我的要求:通讯号和用户号(或全部)。

测试时间(之前10分钟)可以用这样的东西来完成(我为了更容易理解而简化了):

date_default_timezone_set('America/Denver');
$month=;//without leading zeros
$day=;//without leading zeros
$hour=;//24 hour without leading zeros
$min=;//needs leading zeros
if($month==date(n) and $day==date(j)){
    if($hour==date(G)){
        if(($min-date(i))<=10){
            //run command
        }
    }elseif(($hour-1)==date(g)){
        if(($min-date(i))<=(-50)){
            //run command
        }
    }
}

您需要将时区更改为您自己的时区,并以某种方式从数据库中提取日期和时间信息。
脚本的第二部分(运行在一小时的前9分钟内运行的命令)未经测试,但第一部分我刚刚对其进行了快速测试。
希望这可以帮助。

答案 1 :(得分:3)

如果您想要建立邮件队列系统,我建议您查看PEAR::Mail_Queue及相关教程。

您可以在运行10分钟脚本时排队邮件,并通过cron作业每10分钟清空一次邮件队列。您还可以每分钟清空一次邮件队列,并在相关邮件的队列中实施“请勿发送”时间。

或者,您可以每分钟运行一次检查脚本,检查过去十分钟内提醒的项目,并立即发送邮件,这样就无需使用队列系统。

这可以通过记录您上次发送警报的时间来实现(这样您就不会错过任何警报并且不发送警报两次)

希望有所帮助。

答案 2 :(得分:1)

PHP解决方案

我已经考虑过你的问题了,这是我提出的PHP解决方案。

  

#!/opt/lamp/bin/php是我的php解释器的路径。你应该改变它   到你的路径或只是用PHP运行它   -f scheduler.php

<强> scheduler.php

#!/opt/lampp/bin/php
<?php
// For testing purpose I set this to 5 seconds. You should set it to 600.
$time = 5;

while (true) {
    /*  
    let's assume you store the emails scheduled from the database in this
    in memory array.
    */
    $array = array( 
        "Message to run last", #message which is scheduled last.
        "Message to run after first message",
        "Message to run immediately", #message which is scheduled first.
    );

    $message = array_pop($array);    
    while ($message != NULL) {
            echo $message . "\r\n";
            /* 
            For testing purpose I am just simply echoing out messages.
            In here you should sent mails using for exmample
            http://php.net/manual/en/function.mail.php
            */
            $message = array_pop($array); // Get next message.
    }

    /*
    sleep $time. This is the "cron" part of your problem.
    */
    sleep($time); 
}

您应该在bash脚本中运行此脚本以查看它的作用。此外,代码已被很好地记录下来。该脚本应该永远运行(在后台)。

Java解决方案

这也不是PHP唯一的解决方案,但我认为这比我提出的PHP解决方案更好。我还在工作,但我喜欢到目前为止我想出的。

Google App Engine解决方案

我知道这不是PHP解决方案,但是当您无法安装消息队列时,我认为Google App Engine是最佳解决方案。 当我从Brett Slatkin看到这个video introduction到使用Python SDK的谷歌应用引擎时,我被卖给了Google App引擎。它只需要10分钟的时间,您将学习如何创建基本留言簿并将其部署到云端。如果感兴趣,我将尝试在Google的App Engine上解释您需要执行此操作的部分。


  

我想我需要某种消息   队列系统

也许你可以使用谷歌应用引擎的taskqueue来完成任务。任务队列甚至有eta,您可以将其设置为在特定时间运行。 Google App引擎有一个慷慨的free quota。您可以每天免费为该任务添加100,000个队列。

  

但电子邮件部分如何运作

我会使用谷歌应用引擎。您可以使用Google App引擎的mail服务。它还有一个慷慨的免费配额(每天2000个接收者)。我建议你只是从队列中调用邮件api来发送消息。

答案 3 :(得分:0)

我们有一个类似的系统(这是一个ASP.NET应用程序,所以我们有使用内部调度程序来运行它的服务......但细节并不重要)。我们有一个大的消息队列表,其中包含要发送的电子邮件数据,地址和主题行(实际的电子邮件是从模板生成的)。我们的系统工作方式是,一旦填充了一行,我们立即触发一个发送任务,收集所有待处理的电子邮件并发送它们。它试图发送它们3次,如果失败,它们将被置于失败的重新发送状态。我们有一个类似于cron的工作,每5分钟就会运行一次以清除任何失败的任务(如果因为99%的时间它是网络问题,很少会失败)。

答案 4 :(得分:0)

您多久发送一封电子邮件?如果它出现了(现有的cronjob发现它的那一刻,即每10分钟),你可以让寻找remind-me标志的脚本执行此操作:

1 - 在数组中添加对标志所在的每一行的引用,例如

$reminders = array(1, 3, 212);

数组中的每个元素都引用了task表的主键,这里我使用了“tasks”。

2 - 数据库查找完成后,查看$ reminders是否为空,然后运行查询

$query = "SELECT * FROM tasks WHERE id = '".implode(',', $reminders)."'";

获取所有特定于任务的数据

3 - 使用mail向您自己发送包含此数据的电子邮件。

这是你想要的吗?