发送电子邮件作为后台进程 [英] Send emails as a background process

查看:33
本文介绍了发送电子邮件作为后台进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的应用程序中制作时事通讯功能.创建新闻通讯后,我需要发送大约 5000-6000 封电子邮件.发布时事通讯时,它将创建一个电子邮件队列,该队列将存储在数据库中.由于它需要很多时间,我需要在后台运行它.所以我做了一个命令,使用 YiiMailer 和数据库中的电子邮件队列发送邮件.

I want to make a newsletter feature in my application. I need to send emails about 5000-6000 after I create a newsletter. When the newsletter is published it will create an email queue which will be stored in the database. Since it requires a lot of time I need to run it in the background. So I made a command to send the mail using YiiMailer and the email queue from the database.

我的命令正在运行,但它在一段时间后没有完成工作就被终止了.另外我需要在后台运行它,但现在不是.任何帮助表示赞赏.

My command is working, but it is getting terminated after some time without completing the job. Also I need to run it in the background, but now it is not. Any help appreciated.

我的控制器

public function actionSend(){
    $command = new MailQueueCommand("test", "test");
        $command->run(null);
        $this->render('index');

}

我的 MailQueueCommand.php

My MailQueueCommand.php

<?php


class MailQueueCommand extends CConsoleCommand
{

public function run($args)
{
    $criteria = new CDbCriteria(array(
            'condition' => 'success=:success AND attempts < max_attempts',
            'params' => array(
                ':success' => 0,
            ),
        ));

    $queueList = EmailQueue::model()->findAll($criteria);

    /* @var $queueItem EmailQueue */
    foreach ($queueList as $queueItem)
    {


            $mail = new YiiMailer();
            $mail->IsSMTP();                                     
            $mail->Host = 'smtp.gmail.com';  
            $mail->SMTPAuth = true;                            
            $mail->Username = 'xxxx';                            
            $mail->Password = 'xxxxx';                          
            $mail->SMTPSecure = 'tls';                           
            $mail->Port = 587;

            $mail->setFrom('exmampl@gmail.com', 'Name');

        $mail->setTo($queueItem->to_email);

        $mail->setSubject($queueItem->subject);
        $mail->setBody($queueItem->message, 'text/html');

        if ($this->sendEmail($mail))
        {
            $queueItem->attempts = $queueItem->attempts + 1;
            $queueItem->success = 1;
            $queueItem->last_attempt = new CDbExpression('NOW()');
            $queueItem->date_sent = new CDbExpression('NOW()');

            $queueItem->save();
        }
        else
        {
            $queueItem->attempts = $queueItem->attempts + 1;
            $queueItem->last_attempt = new CDbExpression('NOW()');

            $queueItem->save();
        }
    }
}


private function sendEmail($mail)
{
    $sendStatus = false;

    if ($mail->send() > 0)
        $sendStatus = true;

    return $sendStatus;
}

}
?>

推荐答案

基于我发送电子邮件通知的经验

Based on my experience in sending email notifications

您的邮件作业通常会在这两者之间停止的原因是因为通常 php 执行有时间限制,发送 5000,6000 封邮件需要很长时间.使用 Amazon SES 之类的服务,您可以每秒发送 5 个,即 1200 秒或 20 分钟 ..大多数邮件服务器会给您类似或更慢的速度,典型的 php(CLI) 执行时间为 30 秒,这就是您的问题所在是.

The reason usually your mail job gets stopped in between is because usually there is time limit on php execution, and sending 5000,6000 mails will take a long time . Using a service like Amazon SES you can send 5 per second so that is like 1200 seconds or 20 mins ..most mail servers will give you similar or slower speeds, Typical php(CLI) execution time is 30 seconds, which is where your problem is.

我所做的是每批只发送 100-200 封邮件,并每隔一分钟通过 cron 运行控制台命令.它会稍微慢一些,但你会到达那里.

What I do is send only 100-200 mails per batch, and run the console command through cron every one minute.It will be slightly slower but you will get there.

 $criteria = new CDbCriteria(array(
            'condition' => 'success=:success AND attempts < max_attempts',
            'params' => array(
                ':success' => 0,
            ),
            'limit'=>200,
        ));

使用 crontab -e

* * * * * <path-to-yii>protected/yiic MailQueueCommand run &> /dev/null

希望这有帮助..

注意:如果实际使用 SES,这不会有问题,因为它们会将您的所有请求排队并每秒发送 5 个请求,并且实际上没有排队限制.

Note: if actually using SES this won't be a problem as they queue all your requests and send them 5 per second, and there is no limit on queing really.

注意: cron 不像从命令行调用,您在设置它时可能会遇到意外问题.

Note: cron is not like calling from command line you might have unexpected issues setting it up.

这篇关于发送电子邮件作为后台进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆