wordpress cron作业是按顺序执行还是并行执行?

Ahm*_*led 11 php wordpress cron

我试图限制从我的网站发送的电子邮件数量,以应对托管服务电子邮件的限制.我正在使用cron作业和指示堆积数据库中的电子邮件,以检查发送的电子邮件数量是否接近发送的最大电子邮件数量限制.

我这样做的方法是直接执行预定的进程,然后让它"休眠"一段时间(根据它在队列中的位置),然后发送电子邮件并登录数据库.为了进一步解释我使用计划任务和"睡眠"的原因,请考虑以下场景:

  1. 用户尝试注册到我的网站,并希望很快就会向他/她发送电子邮件.因此,如果超过电子邮件/分钟配额,我需要发送一条不同的消息:"我们的服务器很忙,请允许'x'分钟执行所需的任务".
  2. 发送电子邮件的请求都是通过AJAX完成的.在进程中使用"sleep"不是一个选项,因为用户必须等待x分钟,直到"busy message"被回显.
  3. 我尝试使用ob_flush,flush ...等.组合来回应消息,然后服务器在后台处理所有内容,但这从未奏效.AJAX调用始终等待脚本结束以回显结果.
  4. 我需要在单线程PHP语言中使用多线程!作为一种解决方法,我使用了cron作业,其中每个堆积的电子邮件被安排在time()(即直接触发预定作业)执行,该电子邮件挂钩到发送电子邮件的同一功能.使用标志,该函数知道请求是堆积的电子邮件,并使其"休眠",直到电子邮件配额重置所需的时间.

  5. 问题:如果5个人几乎同时注册(虽然我们仍然有一个电子邮件堆),那么我们有5个cron作业,应该同时执行然后再睡一会儿(睡眠时间可能不同,如果堆中的电子邮件数量已经大于电子邮件配额数,然后发送电子邮件.但是,当我检查数据库中的日志时,我发现计划的作业是按顺序执行的,而不是并行执行的.有时它会发生cron作业在另一个结束之前被触发,但它们不会同时触发.

我知道wordpress cron的工作不是真正的cron工作,一旦有人访问网站就会被解雇(我确保在发送注册请求以解雇所有计划任务后刷新页面),但它们似乎是唯一的我的选择,因为我的托管服务器不允许访问服务器既不允许安排cron作业.

以下是执行上述操作的代码的一部分:

//Test example to pile up emails, where quota is set to 2 emails every 30 seconds
$Emails_Threshold = 2;
$Threshold_Duration = 0.5*60;
//Get email indicator info
$Email_Info = $wpdb->get_row( 
"SELECT * 
FROM PileEmails 
WHERE priority = -1 
AND Status='New';"
,ARRAY_A);

if ($sleep ==0 && $Queue_Info_id==0){ //Not a scheduled event
   //Check if there are queued emails
   $Queue_exist = $wpdb->get_row (
    $wpdb->prepare("
                    SELECT Status 
                    FROM PileEmails
                    WHERE Status='Queued';"
                    ,$mail_priority)
                ,ARRAY_A);
  if (!empty($Queue_exist) || ($Email_Info['last_email_time']   > (time()-$Threshold_Duration))){
    if ($Email_Info['count_emails']>=$Emails_Threshold){
           //Code to Pile up
    }
  }else{ 
   //Reset email counter
  }
}else{ 
$wpdb->insert( "PileEmails",$Sleep_Info,$format);
sleep(10); //10 seconds here just as an example
}
//Code to send emails
Run Code Online (Sandbox Code Playgroud)

这是我在超过配额后尝试发送10封电子邮件时登录到数据库的内容.

MYSQL数据库日志

请注意,时间戳在每个日志和后续日志之间有10秒的差异,尽管它们应该同时被触发,每个日志都会休眠10秒,然后所有电子邮件并行发送.

所以我的问题是:为什么wordpress cron按顺序而不是并行地触发预定的作业?以及如何克服这个问题?

任何帮助深表感谢.

Tim*_*man 4

如前所述,安装 cron 插件将有助于管理你的 cron。

为了回答您的问题,Wordpress 使用“cron 锁”并在调用该方法时defined('DOING_CRON')设置瞬态。$lock = get_transient('doing_cron')spawn_cron

因此,如果您查看一下,wp-includes/cron.php您会发现 Wordpress cron 默认情况下不会同时运行,并且每 60 秒不会运行超过一次。

// don't run if another process is currently running it or more than once every 60 sec.
    if ( $lock + WP_CRON_LOCK_TIMEOUT > $gmt_time )
        return;
Run Code Online (Sandbox Code Playgroud)