如何处理带有队列超时的批量邮件发送

时间:2019-09-24 12:53:18

标签: php laravel queue

我的桌子上有超过10万封电子邮件,我想每天发送一些电子邮件:

我在app \ Console \ Kernel.php中添加了时间表:

    select * 
      from comments 
     where comment_id = 203 
     GROUP 
        BY source
         , created_by 
         , attachement_id ;

我有内部工作

$schedule->job(new SendDailyEmails)->dailyAt('09:00');

这可以正常工作,但是一段时间后,该停止可能是因为作业超时。在fail_jobs表中,我收到$users = User::all(); foreach($users as $user){ Maill:to($user->email)->send(new DailyMail($user)); $status = 'sent'; if( in_array($user->email, Mail::failures()) ){ $status = 'failed'; Log::error($user->email . ' was not sent.'); }else{ Log::info($user->email . ' was sent.'); } SentMail::create([ 'email' => $user->email, 'status' => $status ]); } 的消息,消息是Job尝试了太多次或运行了太长时间。由于我在超级用户中将队列尝试次数上限设置为3,因此应该并且仅进行3次。通过测试,它没有尝试再次尝试,因为我收到的是一封邮件而不是3。

所以涉及超时,我不确定默认值是什么,但这很重要,因为我不知道发送所有电子邮件将花费多少时间?

我应该将邮件分成50个组,并为每个组分别调用作业实例吗?

有人对此有很好的答案吗?

2 个答案:

答案 0 :(得分:0)

如果您查看official documentation,就会发现每个邮件都可以排队。

因此,您应该从以下位置更改工作

Mail:to($user->email)->send(new DailyMail($user));

Mail:to($user->email)->queue(new DailyMail($user));

这样,您将把作业生成的每一封邮件都推入队列。建议您创建一个特定的队列,并使用laravel horizon之类的系统进行更好的监视。

还请记住分块发送并延迟发送,因为您的应用程序可能会发生超时错误,但是mailgun之类的提供程序也可能在发现异常活动时阻止您的发送。

答案 1 :(得分:0)

与其尝试在一个班级中一次发送10万多封电子邮件,不如将10万多例Job实例分发给队列工作者

$users = User::all();
foreach($users as $user){
  $schedule->job(new SendDailyEmails($user))->dailyAt('09:00');
}

现在Laravel将在队列中堆叠100k +个作业 s ,并尝试一次为每个用户发送一封电子邮件

class SendDailyEmails implements ShouldQueue
{
  public $user;

  public function __construct(User $user)
  {
    $this->user = $user;
  }

  Maill:to($this->user->email)->send(new DailyMail($user));
    $status = 'sent';
    if( in_array($this->user->email, Mail::failures()) ){
        $status = 'failed';
        Log::error($this->user->email . ' was not sent.');
    }else{
        Log::info($this->user->email . ' was sent.');
    }
    SentMail::create([
        'email' => $this->user->email,
        'status' => $status
    ]);