用crond运行WordPress中的计划任务

WordPress站点运行时需要偶尔在后台定时运行一些任务,如定时发布文章,清空Cache的内容,同步别的站点的RSS Feed等。传统来说,计划任务可以通过Linux系统下的crond实现,但考虑到不是所有的网站托管服务都能让用户设定crontab,因此Wordpress中自带了一套计划任务引擎,姑且称之为WP-Cron,这是Wordpress自带的一套函数,和单独的wp-cron插件不是一回事。

WP-Cron的原理是这样的:虽然用户不能通过crond设置计划任务,但网站随时可能会有用户在点击,只要在用户点击的时候,判断当时是否有需要运行的后台任务,如果则在后台运行该任务,就可以实现类似crond的效果。WP-Cron的实现还是比较轻量级的,虽然后台任务是被用户的访问激活的,但后台任务的执行并不会影响用户的访问速度,因为Wordpress在处理用户请求时,发起单独的一个HTTP请求访问wp-cron.php页面后,并不等待wp-cron.php将后台任务执行完毕,也不继续接收由wp-cron.php返回的数据,而是立即处理用户的访问请求。相关细节可以参见wp-includes/cron.php文件。

虽然WP-Cron有着这么多优点,我还是想把它禁用,原因有2: 首先,我的可以直接使用系统的crond,而WP-Cron最多只是没有时的凑合方案(Workaround);其次,WP-Cron最大的缺点是不能保证任务定时执行,当网站没有用户访问时,WP-Cron就不起作用了。

禁用WP-Cron很简单,编辑wp-config.php,加入一下一行:

define(‘DISABLE_WP_CRON’, true);

然后在你后台系统的crontab文件里,增加下面的内容:

*/15 * * * * root /usr/bin/wget -q – -post-data ” https://www.itkylin.com/wp-cron.php?doing_wp_cron -O /dev/null

上面配置指示,每15分钟,调用wget命令访问站点的wp-cron.php文件,post-data参数指示wget用POST方法,而不是GET方法,这样可以避免WP-Super-Cache这样的缓存插件影响后台任务的正确执行,但post-data传输的数据必须是空内容,否则wp-cron.php会拒绝执行。