跳转到主要内容
alexyao 提交于 19 December 2012

Last updated September 5, 2012. Created by ezraw on May 27, 2005. Edited by jhodgdon, rjacobs, mariomaric, Forest Mars. Log in to edit this page. 翻译:南文子  原文地址:http://drupal.org/node/23714

Cron是在特定时间运行命令的一个后台程序. 这些命令就叫做"cron jobs." Cron 可以运行在 Unix、Linux和Mac servers等系统中. Windows servers使用一个叫 计划任务(Scheduled Task)的程序来运行命令.

对于一个适中的个人站点, 你可能会设置这些定时任务(cron jobs)每天运行一次. 对于更加活跃和站点你可能希望定时任务运行的更频繁——或许每几个小时或每个小时. 这种定期的访问会告诉drupal执行周期性的任务,并且帮助你让你的系统流畅运行.

这有一个视频, 如何设置drupal的计划任务 主要讨论cron并且讲述各种配置计划任务的方法.

cron命令

下面的实例中,定时任务命令会在指定的时间自动激活计划任务:

0 * * * * wget -O - -q -t 1 http://www.example.com/cron.php

上面的例子中, 参数0 * * * *代表任务将要执行的时间. 第一个数字代表分钟——在这个例子中, 是在零分钟时, 或指定小时的开始. (如果这个数字是10, 那么指定的动作会在小时过后10分钟开始运行.) 其它数字含义, 分别是, 小时, 日, 月份 和 某周的某天. 一个 *是一个通配符, 表示 "每一个时间."

这一行剩下的参数主要告诉服务器请求url http://www.example.com/cron.php, 然后服务器运行cron.php代码. 注意: -O 是 "破折号 大写字母O", 不是"破折号零". 当然, 大写O很重要. 如果写成小写o将不会运行。

在Drupal 7中, 一个安全的私有URL用来执行计划任务(cron job). 这个URL可以从管理(Administration) > 报告(Reports)> 状态页面(Status page)的计划任务维护区获取.

URL形式大概如下:

http://www.example.com/cron.php?cron_key=y85HnNQxjdqM-deRXj2Xrp2MJumqe1H...

如果你使用的是D7 就可以把任务指向 http://www.example.com/cron.php的URL替换成你自己安全私有的URL.

这有一个计划任务语法的图表:

# +---------------- 分钟minute (0 - 59)
# |  +------------- 时hour (0 - 23)
# |  |  +---------- 日day of month (1 - 31)
# |  |  |  +------- 月month (1 - 12)
# |  |  |  |  +---- 周的某天day of week (0 - 7) (星期天Sunday=0 or 7)
# |  |  |  |  |
  *  *  *  *  *  要执行的命令

由此, 上面的命令意思是在每月的每周每天的所有小时的0分时 "ping http://www.example.com/cron.php 这个地址。

Drupal是如何调用cron的

每个drupal在安装的时候都需要定期的动作处理维护性的任务,如清理记录文件和检查更新。Cron.php是Drupal用来运行这些维护过程的文件。

例如:如果你的站点是www.example.com, 在浏览器中加载这个http://www.example.com/cron.phpURL就会运行cron维护过程.

这个文件在drupal安装时就会自动创建,很简单的调用这个URL就会运行维护工作,不需要更多的附加条件。

如何建立一个计划任务工作(cron job)

计划任务工作(Cron jobs)是由设置的"定时任务(crontab)"预定义的。 crontab 是一个里面的内容是要运行的命令文本文件,这个文件既可以通过命令行界面进行创建和编辑,如果你的网站管理是基于网络的组件如cpanel 或 Plesk, 你也可以使用网页界面进行创建和编辑。

要想在linux的Plesk控制面版中预定义你的定时任务工作(cron job),转到路径常规组中的设置(Settings) > 计划任务(Scheduled Tasks),选择维护任务运行的系统账户用户(通常是FTP用户),点击"新建计划任务(Schedule New Task)". 设定你的命令运行的时间,你可以使用这篇文章提到过的UNIX定时任务报名表的形式指定时间,然后使用和文章提到的一样的格式指定要运行哪条命令,最后,单击OK

另外, 如果你使用基于网络的控制面版可以向你的空间提供商询问详细的指令说明。

通过下面的命令行编辑一个定时任务:

crontab -e

如果失败了,查看下面的Cron故障检测

添加如下指令的任意一条:

45 * * * *  /usr/bin/lynx -source http://example.com/cron.php 
45 * * * * /usr/bin/wget -O - -q -t 1 http://www.example.com/cron.php
45 * * * * curl --silent --compressed http://example.com/cron.php 

这条指令会在每小时的45分时使用lynx, wgetcurl放问你的cron页面。

提供三种方式是为防止你的服务器是可能没有安装wget、lynx或curl, 任何一种方式都是可以正常工作的。

经常创建计划任务时可以到这个地址了解更多的定时任务文件(crontab file)的语法(英文)。

有很多方法可以配置一个计划任务工作(cron job). 如果你有操作定时任务的全部权限,就可以简单的把上面例子中的命令粘贴一条到定时任务文件中 – 请确保将"example.com"替换为你自己的域名或文件根路径

如果你使用的是共享的虚拟主机,你应该能在主机控制面版中的某处找到定时计划工作配置。一些主机对于不熟悉cron的会提供cron向导来引导你完成cron配置。在win系统中可以使用计划任务工具运行IE浏览器指向你的URL来完成相同的工作。

有些主机商不允许本地环回接口(local loopback)的运行, 那么使用wget, curl 或 lynx 的命令就不能工作。 如果出现这种情况, 并且他们运行PHP作为公共网关接口(CGI) (可以检查你的主机提代商配置看下是不是这种情况), 就可以使用下面的命令运行cron :-

/usr/bin/php /home/sites/example.com/public_html/cron.php

还有一些空间商不允许操作cron文件

如果你的空间商约束了你的CRON权限,则试试下面的办法:

  • 向空间商申请权限,或让他们帮你完成计划任务工作的创建
  • 向某个有服务器权限的管理者申请帮你创建cron job,任何有Unix、 Linux或 Mac服务器管理权限的都可以使用一个cron job来定期访问你的站点。当然也有一些公司会提供cron创建业务
  • 使用Poor Man's Cron模块.
  • 找一个在线cron服务. 很多都是免费的但会有一定的限制条件。

Cron不能保证在确定的时间间隔执行,但Drupal会尽最大可能让它工作的最好,你访问cron.php文件的次数越多, cron运行的时间就会越精确。

计划任务工作(cron jobs)故障排除

确保你的站点不是在维护模式。

如果在运行crontab -e时收到拒绝访问的信息, 你就需要使用sudo:

sudo crontab -e

你或许需要在你的定时任务文件中调整wget, lynx 或 curl 的路径. 例如, 上面的列出的cron实例中包含这一行:

45 * * * *  /usr/bin/lynx -source http://example.com/cron.php

而Lynx或许在你的服务器上其它路径,或根本没有安装。输入下面的命令可以找出Lynx的安装路径:

whereis lynx

或者

which lynx

如果路径不是/usr/bin/lynx, 就需要做适当的调整,在使用wget 和 curl 命令时也一样。如果都没有安装可以向管理员申请帮助。

或许有必要把地址http://example.com/cron.php更换为你自己的Drupal安装路径。例如你可能把drupal安装在子目录中,可能这种形式http://www.example.com/drupal/cron.php).

命令实例

Drupal指令目录有两个脚本文件 cron-curl.sh 和 cron-lynx.sh 。你也可以通过cron来调用这些脚本文件:

45 * * * * /home/www/drupal/scripts/cron-lynx.sh

要注意的是指令中的路径和URL需要更换成你自己的。

以已验证用户的身份运行cron(仅适用D6和更早版本)

如果使用上面的方法触发cron.php, cron任务会以匿名用户的身份运行。对于大多数情况这很正常, 但如果Drupal cron已经被定制成要以确定的站点用户身份运行 (如:hook_cron钩子函数实现的自定义逻辑需要特殊的用户权限), 就要使用下面的脚本代码。这个脚本会在调用cron.php文件前鉴定当前用户身份。

注意在Drupal 7中, cron 永远 以匿名用户的身份运行, 所以这个脚本在 Drupal 7 和或高版本不起作用!

注意这个脚本必须由合适的服务器系统用户身份运行,并且调用时cron.php要替换成你自己的服务器上的cron配置文件名。

#!/bin/sh
# 参考pearlbear 的评论 http://drupal.org/node/479948#comment-1673488 

SITE=https://dev.example.com/			
USERNAME=user.name			
PASS=ChangeMe!!12						

COOKIES=/tmp/cron-cookies.txt			
WGETPARAMS="--quiet -O /dev/null --no-check-certificate --save-cookies $COOKIES --keep-session-cookies --load-cookies $COOKIES"
# 如果你的drupal默认语言不是英语你就需要修改这里
LOGIN="Log%20in"			

wget $WGETPARAMS "${SITE}user"			
wget $WGETPARAMS --post-data="name=$USERNAME&pass=$PASS&op=$LOGIN&form_id=user_login" "${SITE}user"	
wget $WGETPARAMS "${SITE}cron.php"

通过Drush运行Drupal cron

如果你想快速的开始实际应用, 这有一个定时任务实例,是每时的10分时运行cron:

10 * * * * /usr/bin/env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
COLUMNS=72 /usr/local/drush/drush --root=/path/to/your/drupalroot --uri=your.drupalsite.org --quiet cron 

你应该设置要运行计划任务的用户和运行网站服务器软件用户是一样的; 如:如果你运行网站服务器(webserver)的用户是www-data:

sudo -u www-data crontab -e 

更多信息http://drush.ws/docs/cron.html

安全注意事项

在d6中可以直接通过scripts/drupal.sh来运行cron.php. Drupal.sh 允许使用命令行脚本来运行一个drupal页面, 为了实现这个功能,添加下面的命令以运行apache用户的身份运行定时计划工作:

/full/path/to/drupal.sh --root /full/path/to/site/root/ http://default/cron.php 

注意这里的http://default/cron.php 不是示例代码, 必须这么写不能做任务更改。

运行这条指令可以让cron.php阻止不经允许的远程访问。

为了阻止远程访问cron.php, 可以在服务端.htaccess文件或虚拟主机配置文件加入下面的代码:

<Files cron.php>
    Order Deny,Allow
    Deny from all
    Allow from localhost
    Allow from 127.0.0.1
    Allow from xx.xx.xx.xx <-- your IP address
</Files>

如果你使用这种方法并且使用drupal.sh来调用cron.php, 最好不要以root用户的身份来运行cron job,最好使用一个没有特权的账户用户,好点的选择如 Apache账户中的http-service或www-data用户。 这样以无特权用户登陆并调用crontab -e,或是在Debian server上用Apache账户,如你可以添加一个用户名的参数:

sudo crontab -e -u www-data

使用这个方法不好的一点是,任何由cron jobs产生的以“http://default/”开头的URL都不能很好的形成。

多站点

如果你运行多个站点,你可以使用这个建议让你的站点的cron jobs维护更简单。让杂乱最小化,创建一个目录/etc/cron.5min 并且让定时任务每5分钟读取一次这个目录。

*/5 * * * * root run-parts /etc/cron.5min

然后把多站点的单个文件放到/etc/cron.5min directory目录, 一个站点一个文件。这些文件可以命名为"site1", "site2"等等。 -- 要注意的是如果文件名含有点(.) run-parts将会检测失败 。为了确保cron可以访问所有的文件,把这句加到命令提示符中:

$ sudo run-parts --test /etc/cron.5min
然后检查确定你的所有文件都已经列出。

 

/etc/cron.5min目录中的每一个文件都应该包含这一行:

/usr/bin/lynx -source http://(full site URL)/cron.php > /dev/null 2>&1
或者上面的命令也可使用curlwget

 

如果这句没有工作,试着把下面这句加到每个文件的开头:

#!/bin/sh
然后确保所有文件都是可以通过

 

$ sudo chmod u+x /etc/cron.5min/*
命令执行后可运行的。

 

要了解更多关于多站点使用cron的信息,查看本手册的多站点Cron区内容。

安全套接层SSL

当使用SSL时, 调用wget: --no-check-certificate时可以附加一个参数。不要把“--no-check-certificate”放到 -0 和 - 之间。

45 * * * * /usr/bin/wget --no-check-certificate --quiet -O -https://example.com/cron.php 

为cron配置一个编辑器

你可以指定你想使用哪一个文本编辑器(emacs, vi, nano, etc.)来编辑定时任务文件,可以输入这条指令来告诉系统你想用哪一个编辑器:

export EDITOR=nano