在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; } //Log function 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 line chdir(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 correct drupal_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来记录日志,这样更方便一些。
声明:
本站所有文章欢迎转载,所有文章未说明,均属于原创,转载均请注明出处。
本文有效链接:
http://www.drupal001.com/2012/05/php-background-process/
版权所有:
Drupal与高性能网站架构
http://www.drupal001.com
发表评论