- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章PHP curl 并发最佳实践代码分享由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文将探讨两种具体的实现方法, 并对不同的方法做简单的性能对比. 1. 经典cURL并发机制及其存在的问题 经典的cURL实现机制在网上很容易找到, 比如参考PHP在线手册的如下实现方式: 。
复制代码代码如下
function classic_curl($urls, $delay) { $queue = curl_multi_init(); $map = array(); foreach ($urls as $url) { // create cURL resources $ch = curl_init(); // set URL and other appropriate options curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_TIMEOUT, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_NOSIGNAL, true); // add handle curl_multi_add_handle($queue, $ch); $map[$url] = $ch; } $active = null; // execute the handles do { $mrc = curl_multi_exec($queue, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active > 0 && $mrc == CURLM_OK) { if (curl_multi_select($queue, 0.5) != -1) { do { $mrc = curl_multi_exec($queue, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } $responses = array(); foreach ($map as $url=>$ch) { $responses[$url] = callback(curl_multi_getcontent($ch), $delay); curl_multi_remove_handle($queue, $ch); 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, $delay) { $queue = curl_multi_init(); $map = array(); foreach ($urls as $url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_TIMEOUT, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_NOSIGNAL, true); curl_multi_add_handle($queue, $ch); $map[(string) $ch] = $url; } $responses = array(); do { while (($code = curl_multi_exec($queue, $active)) == CURLM_CALL_MULTI_PERFORM) ; if ($code != CURLM_OK) { break; } // a request was just completed -- find out which one while ($done = curl_multi_info_read($queue)) { // get the info and content returned on the request $info = curl_getinfo($done['handle']); $error = curl_error($done['handle']); $results = callback(curl_multi_getcontent($done['handle']), $delay); $responses[$map[(string) $done['handle']]] = compact('info', 'error', 'results'); // remove the curl handle that just completed curl_multi_remove_handle($queue, $done['handle']); curl_close($done['handle']); } // Block for data in / output; error handling is done by curl_multi_exec if ($active > 0) { curl_multi_select($queue, 0.5); } } while ($active); curl_multi_close($queue); return $responses; } 。
3. 两种并发实现的性能对比 改进前后的性能对比试验在LINUX主机上进行, 测试时使用的并发队列如下: http://item.taobao.com/item.htm?id=14392877692 http://item.taobao.com/item.htm?id=16231676302 http://item.taobao.com/item.htm?id=17037160462 http://item.taobao.com/item.htm?id=5522416710 http://item.taobao.com/item.htm?id=16551116403 http://item.taobao.com/item.htm?id=14088310973 简要说明下实验设计的原则和性能测试结果的格式: 为保证结果的可靠, 每组实验重复20次, 在单次实验中, 给定相同的接口URL集合, 分别测量Classic(指经典的并发机制)和Rolling(指改进后的并发机制)两种并发机制的耗时(秒为单位), 耗时短者胜出(Winner), 并计算节省的时间(Excellence, 秒为单位)以及性能提升比例(Excel. %). 为了尽量贴近真实的请求而又保持实验的简单, 在对返回结果的处理上只是做了简单的正则表达式匹配, 而没有进行其他复杂的操作. 另外, 为了确定结果处理回调对性能对比测试结果的影响, 可以使用usleep模拟现实中比较负责的数据处理逻辑(如提取, 分词, 写入文件或数据库等). 性能测试中用到的回调函数为: 。
复制代码代码如下
function callback($data, $delay) { preg_match_all('/<h3>(.+)<\/h3>/iU', $data, $matches); usleep($delay); return compact('data', 'matches'); } 。
数据处理回调无延迟时: Rolling Curl略优, 但性能提升效果不明显. 数据处理回调延迟5毫秒: Rolling Curl完胜, 性能提升40%左右. 通过上面的性能对比, 在处理URL队列并发的应用场景中Rolling cURL应该是更加的选择, 并发量非常大(1000+)时, 可以控制并发队列的最大长度, 比如20, 每当1个URL返回并处理完毕之后立即加入1个尚未请求的URL到队列中, 这样写出来的代码会更加健壮, 不至于并发数太大而卡死或崩溃. 详细的实现请参考: http://code.google.com/p/rolling-curl/ 。
最后此篇关于PHP curl 并发最佳实践代码分享的文章就讲到这里了,如果你想了解更多关于PHP curl 并发最佳实践代码分享的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在 JavaScript 文件中运行 PHP,例如...... var = '';). 我需要使用 JavaScript 来扫描字符串中的 PHP 定界符(打开和关闭 PHP 的 )。 我已经知道使
我希望能够做这样的事情: php --determine-oldest-supported-php-version test.php 并得到这个输出: 7.2 也就是说,php 二进制检查 test.
我正在开发一个目前不使用任何框架的大型 php 站点。我的大问题是,随着时间的推移慢慢尝试将框架融入应用程序是否可取,例如在创建的新部件和更新的旧部件中? 比如所有的页面都是直接通过url服务的,有几
下面是我的源代码,我想在同一页面顶部的另一个 php 脚本中使用位于底部 php 脚本的变量 $r1。我需要一个简单的解决方案来解决这个问题。我想在代码中存在的更新查询中使用该变量。 $name)
我正在制作一个网站,根据不同的情况进行大量 PHP 重定向。就像这样...... header("Location: somesite.com/redirectedpage.php"); 为了安全起见
我有一个旧网站,我的 php 标签从 因为短标签已经显示出安全问题,并且在未来的版本中将不被支持。 关于php - 如何避免在 php 文件中写入
我有一个用 PHP 编写的配置文件,如下所示, 所以我想用PHP开发一个接口(interface),它可以编辑文件值,如$WEBPATH , $ACCOUNTPATH和 const值(value)观
我试图制作一个登录页面来学习基本的PHP,首先我希望我的独立PHP文件存储HTML文件的输入(带有表单),但是当我按下按钮时(触发POST到PHP脚本) )我一直收到令人不愉快的错误。 我已经搜索了S
我正在寻找一种让 PHP 以一种形式打印任意数组的方法,我可以将该数组作为赋值包含在我的(测试)代码中。 print_r 产生例如: Array ( [0] => qsr-part:1285 [1]
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: What is the max key size for an array in PHP? 正如标题所说,我想知道
我正在寻找一种让 PHP 以一种形式打印任意数组的方法,我可以将该数组作为赋值包含在我的(测试)代码中。 print_r 产生例如: Array ( [0] => qsr-part:1285 [1]
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我在 MySQL 数据库中有一个表,其中存储餐厅在每个工作日和时段提供的菜单。 表结构如下: i_type i_name i_cost i_day i_start i_
我有两页。 test1.php 和 test2.php。 我想做的就是在 test1.php 上点击提交,并将 test2.php 显示在 div 中。这实际上工作正常,但我需要向 test2.php
我得到了这个代码。我想通过textarea更新mysql。我在textarea中回显我的MySQL,但我不知道如何更新它,我应该把所有东西都放进去吗,因为_GET模式没有给我任何东西,我也尝试_GET
首先,我是 php 的新手,所以我仍在努力学习。我在 Wordpress 上创建了一个表单,我想将值插入一个表(data_test 表,我已经管理了),然后从 data_test 表中获取所有列(id
我有以下函数可以清理用户或网址的输入: function SanitizeString($var) { $var=stripslashes($var); $va
我有一个 html 页面,它使用 php 文件查询数据库,然后让用户登录,否则拒绝访问。我遇到的问题是它只是重定向到 php 文件的 url,并且从不对发生的事情提供反馈。这是我第一次使用 html、
我有一个页面充满了指向 pdf 的链接,我想跟踪哪些链接被单击。我以为我可以做如下的事情,但遇到了问题: query($sql); if($result){
我正在使用 从外部文本文件加载 HTML/PHP 代码 $f = fopen($filename, "r"); while ($line = fgets($f, 4096)) { print $l
我是一名优秀的程序员,十分优秀!