公司最近举行了一个赛码活动,以小组为单位,耗时最短的获胜。
场景很简单,从一个接口分片下载(HTTP的Range)一段文本,然后找出文本中的数字上传到指定服务器即可。
思路其实大家都一致,感觉就是到了拼最好的语言的时候了。
首先head请求获取到文件的总大小和token,然后多线程下载,正则匹配上传,比对成功就结束。最终java小组的同事用0.6s获胜,其中说用到了http1.1的keep-alive。故此记录一下
上代码
$stime = microtime(true);
for ($i=0; $i < 100; $i++) { //忽略串行
request("https://www.zhanglihu.com");
}
//sleep(20);
echo microtime(true) - $stime;
function request($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
}
这个时候用netstat
命令查看到目标机器的tcp
连接很快达到100个,连接在默认情况下并不能复用
我们尝试注释掉curl_close($ch)
代码继续执行,连接还是很快达到100个。随后我们尝试创建一个全局的curl
句柄,代码如下
$stime = microtime(true);
$ch = curl_init();
// curl_setopt($ch, CURLOPT_FORBID_REUSE, true);//是否连接复用选项,true为不复用
for ($i=0; $i < 100; $i++) {
//file_get_contents("http://www.baidu.com");
request("https://www.zhanglihu.com");
}
//sleep(20);
echo microtime(true) - $stime;
function request($url)
{
global $ch;
//$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
//curl_close($ch);
}
然后再查看连接,惊喜的发现,到目标机器的连接只剩下1个。也就是达到了连接复用的目的。
至于性能,在较少量的情况下并没有什么太大区别,本案例中100次对目标站点内容获取的情况下耗时分别是33.19s
和11.48s
。性能提升还是比较明显。
再说一句,file_get_contents
默认是连接复用的,至少测试如此。本文基于php7.2版本进行的测试。
网友评论