需求, 请求第三方接口获取数据, 单个接口0.1秒, 如果有10万个接口, 那么岂不是得1万秒才能请求完, 所以使用PHP异步测试一下, 其他的方法还有:

1.使用队列, SupserVior 开多个进程

2.使用Guzzle(异步)

3.使用Swoole协程

4.直接使用多进程等

不过最好的方法应该还是使用异步, 不过可能存在两个缺点

1.异步不是很方便后续的逻辑处理, 应为它是一起请求的

2.并发请求会导致第三方接口可能处理不了, 导致503错误,或者是cpu满载(请求淘宝IP查询的接口出现过)

这里做个测试,使用淘宝的一个商品查询接口做请求

一.不使用异步

<?php

/**
* 1个请求 耗时 0.19000s, 平均每个耗时:0.19000s
* 10个请求 耗时 1.60000s, 平均每个耗时:0.16000s
* 100个请求 耗时 14.92400s, 平均每个耗时:0.14924s
* 1000个请求 超时
*
*/ set_time_limit(0);
$time = microtime(true);
echo '<pre>开始时间' . date('Y-m-d H:i:s', time()) . '<br>'; $data = $res =[];
$count = 1000; for ($i=0; $i <$count ; $i++) {
$url = 'https://suggest.taobao.com/sug?code=utf-8&q=%E5%8D%AB%E8%A1%A3&callback=cb';
$res[] = curl_request($url);
} function curl_request($url, $post='', $cookie='', $returnCookie=0)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)');
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
curl_setopt($curl, CURLOPT_REFERER, "http://XXX"); //关闭SSL验证
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); if($post) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
} else {
//curl_setopt($curl, CURLOPT_POST, 1); //使用后大概快了20%, 但是这个是post请求的
} if($cookie) {
curl_setopt($curl, CURLOPT_COOKIE, $cookie);
}
curl_setopt($curl, CURLOPT_HEADER, $returnCookie);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($curl);
if (curl_errno($curl)) {
return curl_error($curl);
}
curl_close($curl);
if($returnCookie){
list($header, $body) = explode("\r\n\r\n", $data, 2);
preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches);
$info['cookie'] = substr($matches[1][0], 1);
$info['content'] = $body;
return $info;
}else{
return $data;
}
} $cost = microtime(true) - $time;
echo "结束时间" . date('Y-m-d H:i:s', time()) . ', 耗时 '. sprintf('%.5f', $cost) . 's, 平均每个耗时:' . sprintf('%.5f', $cost / $count) . 's <br>'; var_dump($res);

二.使用异步请求

<?php

/**
* 1个请求 耗时 0.16300s 平均每个耗时:0.16300s
* 10个请求 耗时 0.33500s 平均每个耗时:0.03350s
* 100个请求 耗时 1.62600s, 平均每个耗时:0.01626s
* 1000个请求 耗时 22.27700s, 平均每个耗时:0.02228s
*
*/ $time = microtime(true);
echo '<pre>开始时间' . date('Y-m-d H:i:s', time()) . '<br>'; set_time_limit(0); $data = [];
$count = 1000; for ($i=0; $i <$count ; $i++) {
$url = 'https://suggest.taobao.com/sug?code=utf-8&q=%E5%8D%AB%E8%A1%A3&callback=cb';
$data[]['url'] = $url;
} function getMultiCurlResult($data = [], $timeout = 120)
{
$request = [];
$requestResource = curl_multi_init();
foreach ($data as $k => $v) {
$option = [
CURLOPT_TIMEOUT => $timeout,//请求超时时间,防止死循环
CURLOPT_RETURNTRANSFER => true,//获取的信息以文件流的形式返回,而不是直接输出。
];
if (!isset($v['url']) || !$v['url']) return null;
$option[CURLOPT_URL] = trim($v['url']);
if (stripos($v['url'], 'https') === 0) $option[CURLOPT_SSL_VERIFYPEER] = false; if (isset($v['data'])) {//如果设置了请求参数,则是POST请求
$option[CURLOPT_POST] = true;
$option[CURLOPT_POSTFIELDS] = http_build_query($v['data']);
} //启动一个curl会话
$request[$k] = curl_init();
//设置请求选项
curl_setopt_array($request[$k], $option);
//添加请求句柄
curl_multi_add_handle($requestResource, $request[$k]);
} $running = null;
$result = [];
do {//执行批处理句柄
//CURLOPT_RETURNTRANSFER如果为0,这里会直接输出获取到的内容.如果为1,后面可以用curl_multi_getcontent获取内容.
curl_multi_exec($requestResource, $running);
//阻塞直到cURL批处理连接中有活动连接,不加这个会导致CPU负载超过90%.
curl_multi_select($requestResource);
} while ($running > 0); foreach ($request as $k => $v) {
$result[$k] = curl_multi_getcontent($v);
curl_multi_remove_handle($requestResource, $v);
}
curl_multi_close($requestResource); return $result;
} $res = getMultiCurlResult($data); $cost = microtime(true) - $time;
echo "结束时间" . date('Y-m-d H:i:s', time()) . ', 耗时 '. sprintf('%.5f', $cost) . 's, 平均每个耗时:' . sprintf('%.5f', $cost / $count) . 's <br>'; var_dump($res);

可以看出,异步的效果还是很明显的

PHP CURL 异步测试的更多相关文章

  1. 【测试】Gunicorn , uWSGI同步异步测试以及应用场景总结

    最近使用uwsgi出了一些问题,于是测试下Gunicorn测试对比下 环境 一颗cpu 1g内存 Centos系统 Django作为后端应用,Gunicorn默认模式和异步模式,响应基本是无阻塞类型 ...

  2. 蛋疼的mocha库-promise异步测试

    mocha 测试库的使用 错误的处理异步测试 异步当出现断言错误的时候,他会抛出错误,但不会把这次测试当作失败,就是正确的顺利通过测试了,很无语. promise的reject会在then的第二个函数 ...

  3. 用telnet和php的curl库测试http

    一.telnet测试http telnet简介     Telnet协议是TCP/IP协议族的其中之一,是Internet远端登录服务的标准协议和主要方式,常用于网页服务器的远端控制,可供使用者在本地 ...

  4. Spring MVC 异步测试

    从spring3.2开始,支持servlet3的异步请求,这对于处理耗时的请求如缓慢的数据库查询是非常有好处的,不至于很快的耗光servlet的线程池,影响可扩展性. 让我们先来了解一下servlet ...

  5. mocha框架下,异步测试代码错误造成的问题----用例超时错误

    今天用抹茶(mocha)做个测试,发现有一个测试项目总是超时: describe("DbFactory functions",function(){ it("query ...

  6. CURL命令测试网站打开速度

    curl -o /dev/null -s -w %{time_namelookup}:%{time_connect}:%{time_starttransfer}:%{time_total} http: ...

  7. curl命令测试https

    curl -vosa --resolve pic.test.net::222.241.7.179 https://pic.test.net/UploadFiles/201312031744347965 ...

  8. curl/wget 测试http请求的响应头信息

    1. wget –debug wget可以使用debug信息来查看信息头,如下: [root@localhost ~]# wget --debug http://192.168.1.101:8080/ ...

  9. curl 异步捉取数据类

    <?php class RequestLib { /** * GET 请求 * @param string $url */ public static function http_get($ur ...

随机推荐

  1. 帆软报表PC端实施报表心得体会

    1.报表制作完成后,预览时自动显示查询内容,在控件处设置: 2.求一列数据的最小值(除去0),并对最小值字体加粗标绿,需要对对应单元格设置条件属性,并插入公式:C6 = min(greparray(C ...

  2. Java 虚拟机 - GC机制

    GC机制的一些总结 https://blog.csdn.net/super_qing_/article/details/85263991 https://blog.csdn.net/yhyr_ycy/ ...

  3. 【JZOJ3424】粉刷匠

    description 赫克托是一个魁梧的粉刷匠,而且非常喜欢思考= = 现在,神庙里有N根排列成一直线的石柱,从1到N标号,长老要求用油漆将这些石柱重新粉刷一遍.赫克托有K桶颜色各不相同的油漆,第i ...

  4. [JZOJ 5788] 餐馆

    思路: 考虑树形dp. 我们设\(dp[i][j][0/1]\)表示在\(i\)为根的子树中花费\(j\)单位时间,最终回到/不必回到\(i\)的最大收益. 转移三种: \(dp[x][j][0] = ...

  5. spring mvc多环境下配置文件的设置

    在实际开发时经常需要把一些配置信息写在配置文件,比如mysql的主机地址.端口号.用户名和密码等.另外,在开发代码时可能用一套配置参数,而部署到测试环境时又会用另一套配置参数,测试完毕再部署到线上环境 ...

  6. arcmap分类标注问题

    在给图层标注的时候,经常出现冲突后有些标注出不来,需要将某些个别的点要素进行标注位置调整,如下图: 处理步骤如下, (1)打开Maplex标注引擎.从ToolBars中打开Labeling工具,勾选U ...

  7. CSS 常用的兼容性调试技巧

    1.实现所有浏览器主页居中 Firefox下主页居中代码:.box{margin:0px auto} IE5.5下主页居中代码:body{text-align:center;} 将以上两种代码,合在一 ...

  8. Activiti业务键(businessKey)

    问题:如何让业务对象和对应的流程 关联? 发现ProcessInstance 有个方法getBusinessKey()可以得到一个businessKey. ProcessInstance 对应数据库中 ...

  9. C++单纯的指针传参的问题

    C++指针传参也是单纯的复制一份地址,如下代码: #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace st ...

  10. (转)nginx配置location总结及rewrite规则写法

    注: rewrite 只能对域名后边的除去传递的参数外的字符串起作用,并且要写全域名后面的部分,如: http://i.com:9090/php/midou/admin.php/index/login ...