错误信息

Deprecated function: The each() function is deprecated. This message will be suppressed on further calls 在 menu_set_active_trail() (行 2405/data/itxueku/includes/menu.inc).

PHP后台进程/异步处理的用法及在Drupal中的应用

浏览:118
在Web的HTTP请求中,经常有些消耗CPU耗时的操作,并且这些操作并不是立刻就需要得到执行结果,这时候,我们最好使用异步的后台进程处理来提高网站的性能。在异步处理框架中,Gearman是一款优秀的异步处理程序并且支持多种语言和平台,但正是由于这种兼容性的,所以使用起来稍微复杂,所以本文暂不介绍Gearman的使用。

PHP在Linux上运行,可以通过一些函数调用系统shell,让shell在后台运行,这样就可以打开一个后台进程然后立即返回,这种方法可以把一些耗时的操作独立出来,进而提升网页的响应时间,提升用户的体验。


笔者基于Drupal,在其上写了几个后台进程的API,经测试运行完美,极大得提高了一个耗时的页面操作,代码参阅如下:



主要函数 drupal_background_process,





/**
 * @param array $callback_params {'callback' : [name], 'params' : [args]}
 * @return type 
 */function drupal_background_process($callback_params) {
  $cid = "drupal_background_" . time();
  cache_set($cid, $callback_params);   $php =  dirname($_SERVER['SCRIPT_FILENAME']) . '/index_bg.php';
  pclose(popen("php $php $cid > /dev/null &", 'r'));   return true;} //Logfunction drupal_background_log($txt) {
  global $conf;   $log = isset($conf['background_log']) ? $conf['background_log'] : '/tmp/drupal-background.log';
  if (isset($conf['background_log_enable']) && $conf['background_log_enable']) {file_put_contents($log, "\n" . $txt, FILE_APPEND);
  }}

新建一个Drupal的bootstrap文件,命名为index_bg.php,和Drupal的index.php放在一起,内容如下:





//bootstrap file//make sure current directory is drupal base especiall command linechdir(dirname(__FILE__)); require_once './includes/bootstrap.inc';drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); global $conf;$conf['background_log_enable'] = TRUE; if ($argc > 1) {
  $cid = $argv[1];}elseif (isset($_GET['cid'])){
  $cid = $_GET['cid'];} 
drupal_background_log(">>>$cid"); if ($cache = cache_get($cid)) {
  $object = (object)$cache->data;   //drupal_background_log("DATA:\n" . serialize($cache->data));   if (isset($object->callback)) {if (!isset($object->params) || !is_array($object->params)) {  $object->params = array($object);} //Log and check if the 1st and second arguments are correctdrupal_background_log('Execute: ' . $object->callback); call_user_func_array($object->callback, $object->params);
  } 
  cache_clear_all($cid);}else {
  drupal_background_log("NOT FOUND CID \n");} 
drupal_background_log("DONE\n");

示例用法:





drupal_background_process(array('callback' => 'function_name', 'params' => array(1,2)));

注意:该函数没有支持windows平台,不过windows平台也支持后台命令,大家可以在网上找一下相关的命令写法,替代Linux上的写法即可。
另外如果不使用独立的log函数也可以使用Drupal默认的watchdog来记录日志,这样更方便一些。



top