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

标签 php wordpress cron

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

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

  1. 一位用户尝试注册我的网站,并希望尽快向他/她发送一封电子邮件。因此,如果超过每分钟的电子邮件配额,我需要发送一条不同的消息:“我们的服务器正忙,请允许 'x' 分钟来执行所需的任务”。
  2. 发送电子邮件的请求都是通过 AJAX 完成的。在进程本身中使用“ sleep ”不是一种选择,因为用户将不得不等待 x 分钟,直到回显“忙消息”。
  3. 我尝试使用 ob_flush、flush...等。组合来回显消息,然后服务器在后台解决所有问题,但这从来没有奏效。 AJAX 调用一直在等待脚本结束以回显结果。
  4. 我需要单线程PHP语言中的多线程!作为一种解决方法,我使用了 cron 作业,其中每封堆积的电子邮件都计划在 time() 执行(即直接触发计划的作业),它与发送电子邮件的相同功能 Hook 。使用标志,该函数知道请求是一堆电子邮件并使其“休眠”,直到电子邮件配额重置所需的时间。

  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

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

MYSQL database logs

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

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

非常感谢任何帮助。

最佳答案

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

为了回答您的问题,Wordpress 使用“cron lock”defined('DOING_CRON')并设置一个 transient $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;

关于php - wordpress cron 作业是顺序执行还是并行执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40544078/

相关文章:

php - Composer 类加载器命名空间问题

php - WooCommerce - 将产品类别添加到订单详细信息表

html - CSS - 如何将 <h1> 和 <h2> 标签包裹在 float 的 div 周围

php - Facebook API 中的标签搜索

php - 如何将到期日期存储在数据库中并在日期运行(删除)脚本

php - 如何检索推送通知 php 的 ck.pem 文件

php - Laravel 8+ 上的 unisharp/laravel-ckeditor 无法安装包

javascript - 即时创建下拉菜单

一个文件夹中的 PHP 文件正在执行,但在其他几个文件夹中没有执行

ubuntu - 如何防止 start-stop-daemon 在 cronjob 中创建多个实例?