You are here

Drupal Queue简介及代码实例

Drupal Queue 是Drupal 7提供的新功能。

Queue items to allow later processing.

The queue system allows placing items in a queue and processing them later. The system tries to ensure that only one consumer can process an item.

翻译成中文,大概意思就是:

Queue条目可以延迟操作。

Drupal Queue用户按照序列化执行一定的操作。Queue系统确保每一次系统消费可以处理一个项目。

根据以上描述,Queue有如下特性

  • 序列化

  • 操作延迟化

  • 序列里的条目只会被成功执行一次。

考虑一个具体的场景:比如系统有10W用户,要求给10W用户批量发送邮件。
如果一次性发送,显然是对系统资源一个很大的消耗。
同时如果在发送到第N个邮件的时候,因为各种原因,邮件发送中断。这个N值捕捉不到,可能要面临重新发送的风险;对中断之前已经发送邮件的用户,会收到重复的邮件。 这显然不是一个很好的用户体验。

如果用Queue思想来处理上述操作,我们可能需要做如下如下事情。
1: 定义一个发送邮件序列(Email Queue),同时指定一个调用来处理序列中的条目。
2: 在Email Queue中创建条目。针对这个场景,会创建一个有10W个条目邮件发送的序列。
3: 执行Queue序列中的操作。
 序列执行成功后,会从Queue中删除。这个确保邮件不会被重复发送。
 
下面代码案例,教你如何在Drupal下面使用Queue API如何一步步实现上面的操作。
1: 定义一个发送邮件序列(Email Queue),指定回调函数。

function mymodule_cron_queue_info() {
  $queues = array();
  $queues['email_queue'] = array(
    'worker callback' => '_send_email',
  );
  return $queues;
}
function _send_email($user) {
  //如何使用druapl_mail,请参考,这个不是本文重点,不做详细探讨。
  //http://drupal.stackexchange.com/questions/27063/how-to-send-html-email/27103#27103
  drupal_mail('mymodule', 'email_queue', $user->email, language_default(),$params,$mailfrom,TRUE);
}

 2: 在Email Queue中创建条目。针对这个场景,会创建一个有10W个条目邮件发送的序列。

function create_email_queue_item() {
  $queue = DrupalQueue::get('email_queue');
  $users = entity_load('user');
  foreach($users as $user) {
    $queue->createItem($user);
  }
}

 关于这个函数如何执行,你可以做个表单,在表单的submit里面调用create_email_queue_item()。或者根据实际情况来灵活掌握。

3:执行Queue序列中的操作。
 Queue在什么时候被执行?答案是cron。
 所以定义好以上Queue,如果系统没有设置cron,queue操作不会被执行到。
 //如果你想问cron是神马?自己补充知识去。或者以后有空会介绍下。
 Queue执行遵循FIFO(First In First Out)原则,即先创建的item会被先执行,如果执行成功,则此item会被删除并执行下一个item。如果执行不成功,则该item不会被删除;在下一次cron的时候,会被再次执行。这样确保每一个Queue里面item不会被重复执行。

啰嗦了这么多,如果还是有疑惑,自己啃英文把。
http://getlevelten.com/blog/randall-knutson/cron-queues-processing-large...

一些与Drupal Queue有关的模块:
https://drupal.org/project/queue_ui
https://drupal.org/project/views_queue

//在Drupal 6下面没有Queue,如果你也想在Drupal 6下面使用Queue功能,请使用如下模块。
https://drupal.org/project/drupal_queue