Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在电子邮件队列中发送优先邮件的最佳方式是什么?_Php_Mysql_Email_Cron - Fatal编程技术网

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

Php 在电子邮件队列中发送优先邮件的最佳方式是什么?,php,mysql,email,cron,Php,Mysql,Email,Cron,数以百万计的邮件插入MySQL表“EmailQueue”,其中包含以下字段: id-BigInt(20) 电子邮件地址-Varchar(300) 消息-文本 状态-枚举('Pending'、'Prioritized'、'Processing'、'Processed') 已创建\u datetime-datetime 发送日期时间-日期时间 通常情况下,行将以“挂起”状态插入,但一些高优先级邮件(如忘记/重置密码)将以“优先”状态列插入 cron作业将每小时运行一次,并以循环的形式发送邮件,每个循

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

  • id-BigInt(20)
  • 电子邮件地址-Varchar(300)
  • 消息-文本
  • 状态-枚举('Pending'、'Prioritized'、'Processing'、'Processed')
  • 已创建\u datetime-datetime
  • 发送日期时间-日期时间
  • 通常情况下,行将以“挂起”状态插入,但一些高优先级邮件(如忘记/重置密码)将以“优先”状态列插入

    cron作业将每小时运行一次,并以循环的形式发送邮件,每个循环中包含20000封邮件,直到完成所有邮件的发送。现在,我想先发送优先级排序的邮件,即使cron作业正在运行,这些邮件也可以添加到电子邮件队列中

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

    如果我们忽略“在cron运行时添加”一秒钟,这将首先选择“优先顺序”:

    ORDER BY FIELD(status, "Prioritized"), id ASC
    
    这将对status=优先排序的所有行进行排序,然后按id排序


    在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
        }
    }
    

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

    SELECT * 
    FROM EmailQueue 
    WHERE status IN ('Pending','Prioritized') 
    ORDER BY status DESC, created_datetime ASC
    LIMIT 0,100;
    
    结果是,每次运行查询时,您都会首先得到优先排序的电子邮件,然后是待处理的电子邮件,这两个电子邮件都是按最早的电子邮件排序的

    您可以根据需要运行此批处理任意次数,直到队列耗尽,或者每小时最多运行200次,以符合20000小时的限制


    我假设当您开始处理时,您将状态更改为
    处理
    ,完成后,您将状态更改为
    已处理
    。这就是为什么您总是从0开始,而不是从一个递增的数字开始。

    如果您想让它在作业已经运行的情况下看到它们,那么cron作业只需在发送每封电子邮件之前再次查询,以检查是否有任何内容移动到了队列的顶部。听起来效率不高。如果它们非常紧急,为什么不每隔5分钟左右运行一次作业,并使用SQL“ORDER BY”将优先顺序列在列表的首位,然后只发送以前未发送过的任何内容呢?如果由于某种原因,您每小时发送的数据绝对不能超过20000个,则可以使用DB字段上的时间戳来检查一小时内所有运行到目前为止发送的数据量。@ADyson valid point