wp-cron的问题
Wordpress内置wp-cron的模块,可以用来执行定时任务,比如定时检查更新,定时发布文章等都需要用到,属于必备功能。但是该模块的特点是:它只能在用户发起请求时检查定时任务。这个特点导致了一个问题:没有用户访问时,那定时任务就得不到执行;有用户访问时,某个用户会因为定时任务在执行而响应很慢甚至超时。因此,在生产环境下使用wp-cron是不明智的。
更好的做法是开启一个独立的进程执行这些定时任务——这里使用crontab + wp-cli实现这种做法。(如果你不使用wp-cli,也可以,但是wp-cli,但是在有wp-cli的情况下,你可以方便地查看各个任务的具体执行情况,和对任务做精确的控制。没有命令行工具的情况下就有点要靠猜了)
两步完成优化
1.禁用wp-cron:修改wp-config.php,设置DISABLE_WP_CRON为true:
define('DISABLE_WP_CRON', true);
2.通过crontab定期执行任务
添加以下任务到crontab中(每分钟检查过期任务,如果有就执行)
* * * * * cd /var/www/html && /usr/local/bin/wp cron event run --due-now > /dev/null
就是这么简单。
如何判断定时任务正常执行?
1.首先确认crontab有正常调用你的命令
查看下cron的日志: tail /var/log/cron,看到类似如下的日志说明crontab有在正常调用命令。
Dec 7 11:40:01 aliyun CROND[9189]: (liu) CMD (cd /var/www/html && /usr/local/bin/wp cron event run --due-now > /dev/null) Dec 7 11:40:01 aliyun CROND[9190]: (liu) CMD (/usr/lib64/sa/sa1 1 1) Dec 7 11:41:01 aliyun CROND[9285]: (liu) CMD (cd /var/www/html && /usr/local/bin/wp cron event run --due-now > /dev/null)
2.然后确认你的命令有正确执行
两种方法:
一、可以去掉`> /dev/null`,这样每次crontab执行的输出都会写入邮件,通过mail命令可以看到每次的执行结果。
二、另外一种判断方法是,通过wp cron event list判断,下面着重讲这个方法。
如下示例,你会看到有一些任务的next_run_relative为now,它们表示这些任务该执行了。如果你过了1分钟再查看,它们的状态都没变化,说明任务并没有得到执行。
$wp cron event list +------------------------------------------+---------------------+-----------------------+------------+ | hook | next_run_gmt | next_run_relative | recurrence | +------------------------------------------+---------------------+-----------------------+------------+ | jetpack_display_posts_widget_cron_update | 2018-12-06 10:48:49 | now | 10 minutes | | jetpack_sync_cron | 2018-12-06 10:48:55 | now | 5 minutes | | jetpack_sync_full_cron | 2018-12-06 10:48:55 | now | 5 minutes | | jp_sitemap_cron_hook | 2018-12-06 10:52:42 | 1 minute 59 seconds | 12小时 | | jetpack_clean_nonces | 2018-12-06 11:08:49 | 18 minutes 6 seconds | 1小时 | 。。。 +------------------------------------------+---------------------+-----------------------+------------+
反之,如果任务得到了执行,那些为`now`的状态应该会变掉,如下面的结果所示:
$wp cron event list +------------------------------------------+---------------------+-----------------------+------------+ | hook | next_run_gmt | next_run_relative | recurrence | +------------------------------------------+---------------------+-----------------------+------------+ | jetpack_sync_cron | 2018-12-07 03:53:55 | 41 seconds | 5 minutes | | jetpack_sync_full_cron | 2018-12-07 03:53:55 | 41 seconds | 5 minutes | | jetpack_display_posts_widget_cron_update | 2018-12-07 03:58:49 | 5 minutes 35 seconds | 10 minutes | | jetpack_clean_nonces | 2018-12-07 04:08:49 | 15 minutes 35 seconds | 1小时 | 。。。 +------------------------------------------+---------------------+-----------------------+------------+
配置过程中碰到的问题
Q:执行wp cron event run --due-now时,可能出现下面的提示:
PHP Notice: Undefined index: HTTP_HOST
A:在wp-config.php中添加
if (defined('WP_CLI') && WP_CLI) { $_SERVER['HTTP_HOST'] = 'localhost'; }