Skip to content

Instantly share code, notes, and snippets.

@fleeto
Last active August 29, 2015 14:02
Show Gist options
  • Save fleeto/48886a54242b04af2f06 to your computer and use it in GitHub Desktop.
Save fleeto/48886a54242b04af2f06 to your computer and use it in GitHub Desktop.
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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment