在电子邮件队列中发送优先邮件的最佳方式是什么?

时间:2017-09-12 14:33:01

标签: php mysql email cron

将数以百万计的邮件插入MySQL表“EmailQueue”中,其中包含以下字段,

  1. id - BigInt(20)
  2. email_address - Varchar(300)
  3. message - text
  4. status - enum('待定','优先','处理','已处理')
  5. created_datetime - datetime
  6. sent_datetime - datetime
  7. 通常,行将以“待定”状态插入,但会在状态列中插入一些优先级高的邮件,例如忘记/重置密码。

    cron作业将每小时运行一次,并在每个循环中将批量的20000封邮件作为循环发送,直到完成发送所有电子邮件。现在我想首先发送优先邮件,即使cron作业正在运行,也可以将其添加到电子邮件队列中。

    实现这一目标的最佳方法是什么?我不确定stackoverflow是否是提出这个问题的地方,但不确定更好的地方。感谢您提前提供任何帮助。

2 个答案:

答案 0 :(得分:1)

如果我们忽略"在cron运行时添加"一秒钟,这将选择' Prioritized'第一:

ORDER BY FIELD(status, "Prioritized"), id ASC

这将对所有行进行排序,其中status = Prioritized然后按ID排序。 More info/examples here

在 cron运行时添加更加困难,这成为一个逻辑挑战。如果您执行SELECT * FROM emails ORDER BY FIELD(status, "Prioritized"), id ASC,则在选择时选择数据中的数据。如果在您运行查询后添加了项目,则它不会出现在返回的数据集中。

为了得到你想要的东西,你需要将你的代码分成更小的选择:

$continueProcesss = false;
$current = 0;
$itemsPerBatch = 25;
while( $continueProcesss ){
    $query = "SELECT * FROM emails ORDER BY FIELD(status, 'Prioritized'), id ASC` 
              LIMIT $current,$itemsPerBatch";
    $result = yourQueryMethod($query);
    if( $result->num_rows===0 ){
        $continueProcesss = false;
        break;
    } else{
       $current += $itemsPerBatch; // next round, we skip another $itemsPerBatch rows
    }
}

答案 1 :(得分:0)

这是使用正确查询的问题,例如,如果您知道作业将在每个电子邮件中运行,直到队列耗尽:

SELECT * 
FROM EmailQueue 
WHERE status IN ('Pending','Prioritized') 
ORDER BY status DESC, created_datetime ASC
LIMIT 0,100;

结果是,每次运行查询时,首先会获得优先级的电子邮件,然后是最早的电子邮件,这些电子邮件都是由最早的电子邮件排序的。

您可以多次运行此批次,直到队列耗尽或每小时最多200次以匹配20,000小时限制。

我假设您在开始处理时将状态更改为Processing,完成后您将状态更改为Processed。这就是为什么你总是从0开始而不是增量数字。