php cURL和Rolling cURL并发方式比较
在实际项目或者自己编写小工具(比如新闻聚合,商品价格监控,比价)的过程中,通常需要从第3方网站或者API接口获取数据,在需要处理1个URL队列时,为了提高性能,可以采用cURL提供的curl_multi_*族函数实现简单的并发。 1. 经典cURL并发机制及其存在的问题经典的cURL实现机制在网上很容易找到,比如参考PHP在线手册的如下实现方式: 代码如下: function
classic_curl($urls, $queue = curl_multi_init(); $map = array(); foreach ($urls as // $ch = curl_init(); // curl_setopt($ch, curl_setopt($ch, curl_setopt($ch, curl_setopt($ch, // curl_multi_add_handle($queue, $map[$url] } $active = null; // do { $mrc = curl_multi_exec($queue, } ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active > 0 && $mrc == CURLM_OK) { if (curl_multi_select($queue, do { $mrc = curl_multi_exec($queue, } ($mrc == CURLM_CALL_MULTI_PERFORM); } } $responses = array(); foreach ($map as $responses[$url] curl_multi_remove_handle($queue, curl_close($ch); } curl_multi_close($queue); return $responses; } 首先将所有的URL压入并发队列,然后执行并发过程,等待所有请求接收完之后进行数据的解析等后续处理. 在实际的处理过程中,受网络传输的影响,部分URL的内容会优先于其他URL返回,但是经典cURL并发必须等待最慢的那个URL返回之后才开始处理,等待也就意味着CPU的空闲和浪费. 如果URL队列很短,这种空闲和浪费还处在可接受的范围,但如果队列很长,这种等待和浪费将变得不可接受. 2. 改进的Rolling cURL并发方式仔细分析不难发现经典cURL并发还存在优化的空间,优化的方式时当某个URL请求完毕之后尽可能快的去处理它,边处理边等待其他的URL返回,而不是等待那个最慢的接口返回之后才开始处理等工作,从而避免CPU的空闲和浪费. 闲话不多说,下面贴上具体的实现: 代码如下: function
rolling_curl($urls, $queue = curl_multi_init(); $map = array(); foreach ($urls as $ch = curl_init(); curl_setopt($ch,$url); curl_setopt($ch,true); curl_multi_add_handle($queue, $map[(string) } $responses = array(); do { while (($code = curl_multi_exec($queue, if ($code != CURLM_OK) { break; // while ($done = curl_multi_info_read($queue)) // $info = curl_getinfo($done['handle']); $error = curl_error($done['handle']); $results = callback(curl_multi_getcontent($done['handle']), $responses[$map[(string) // curl_multi_remove_handle($queue, curl_close($done['handle']); } // if ($active > 0) { curl_multi_select($queue, } } ($active); curl_multi_close($queue); return $responses; } 3. 两种并发实现的性能对比改进前后的性能对比试验在LINUX主机上进行,测试时使用的并发队列如下:
http://a.com/item.htm?id=14392877692 代码如下: function
callback($data, preg_match_all('/ (.+)/iU',$data, $matches); usleep($delay); return compact('data', } 数据处理回调无延迟时: Rolling Curl略优,但性能提升效果不明显。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |