跳转到主要内容
dustise 提交于 16 June 2014

作者:thirdandgrove 原文:Best practices for using Drupal's cron system: hook_cron()

如果你成功的设置了Drupal Cronhook_cron()提供了一种不依赖页面请求的方式来进行后台任务,然而,Cron的滥用也有可能造成性能问题,甚至威胁数据完整性。

这里提供一些我们在实际工作中得来不易的一些Cron方面的最佳实践:

第一条:用变量控制Cron。

hook_cron()的每一次调用都封装在一个变量检查的条件之内,这个变量的缺省值是TRUE,想要禁止这个CRON,只要把这个变量创建起来并赋值为False即可,当你的CRON过程失控或者消耗太多资源时,这一手段是非常有效的。

/**
 * Implements hook_cron().
 */
function example_cron() {
  if (variable_get('example_process_users_during_cron', TRUE)) {
    module_load_include('inc', 'example');
    example_process_users();
  }
}

第二条:在inc文件中实现逻辑。

需要注意的是,Drupal很重:每次页面请求都会载入所有被启用的Module文件。所以module文件里只应该包含每次页面请求都需要执行的部分,Cron代码运行频率很低,因此不应包含在module文件里。这也是一条适用于其他模块开发的最佳实践。

(这是快速得知一个模块作者是否真正了解Drupal的办法。)

第三条:Drush命令。

即使你不想使用Drush来运行Cron,也应该创建一个简单的Drush命令来运行你的代码。在你的CRON过程消耗过高的时候,可以利用前面第一条说的方法禁用这条CRON命令,然后做一个系统的Cron过程,在恰当的时机来利用drush直接运行这段代码。可以根据开销情况,用这种方法来单独调节每个Cron任务。这是一种未雨绸缪的措施。

下面是example.drush.inc文件里的示例代码:

/**
 * Implements hook_drush_command().
 */
function example_drush_command() {
  return array(
    'example-process-users' => array(
      'description' => dt('Process the user accounts.'),
      'alias' => array('epu'),
    ),
  );
}

/**
 * Process user accounts.
 */
function drush_example_example_process_users() {
  module_load_include('inc', 'example');
  example_process_users();
}

第四条:批处理。

在开发之前,不要仅仅想着今天或这个月的处理量,而应该想想一年甚至更大量的情况,确保你的处理效率能够适应数据的增长。

这意味着,需要在代码重一次处理大批记录,可以用一个变量来指定每次的处理量,或者可以哦能够队列的方式来处理。

第五条:我真的需要Cron么?

Drupal的hook_cron()是一个很适合处理简单,常见任务的方式。不过如果你要处理大量数据,或者复杂任务,你应该使用一些更专门的方法,例如Drupal 7的Queue System甚至Drupal之外的方案,例如Jenkins CI

Drupal 版本