需求, 请求第三方接口获取数据, 单个接口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. day20 装饰器补充

    Python之路,Day8 = Python基础8 装饰器from functools imoort wraps # 保留原函数所有信息,比如:用__doc__查看注释的时候,显示原来的注释def f ...

  2. 软件-开发工具:Gradle

    ylbtech-软件-开发工具:Gradle Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具.它使用一种基于Groovy的特定领域语言(DSL)来声明 ...

  3. JAVA 文件的上传下载

    一.上传文件 1.使用 transferTo 上传 @ResponseBody @RequestMapping(value = "/file/upload") public Res ...

  4. day 62 Django基础之jQuery操作cookie

    Django基础之jQuery操作cookie   jquery之cookie操作 定义:让网站服务器把少量数据储存到客户端的硬盘或内存,从客户端的硬盘读取数据的一种技术: 下载与引入:jquery. ...

  5. Caused by: java.lang.NoSuchMethodError: org.hibernate.engine.spi.SessionFactoryImplementor.getProperties()Ljava/util/Properties;

    报错信息 Error starting ApplicationContext. To display the auto-configuration report re-run your applica ...

  6. python安装requests第三方模块

    2018-08-28 22:04:51 1 .下载到桌面后解压,放到python的目录下 ------------------------------------------------------- ...

  7. Web-动态页面

    <!doctype html>01 - JavaEE- JSP - EL&JSTL figure:first-child { margin-top: -20px; } #write ...

  8. 关于切片/截取(slice)和random模块的使用(实例:猜单词小游戏)

    切片和random的使用在源码中都有注释(可以直接下载):https://github.com/NoobZeng/GuessWords 1. README.MD 基于Python的猜单词游戏 猜单词小 ...

  9. Java之实现多线程

    保证同步的几种方法: (1) 同步方法,synchronized 关键字修饰方法.由于Java中的每个对象都有一个内置锁,当用该关键词修饰时,内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则 ...

  10. netty http 服务器

    HttpFileServer package com.zhaowb.netty.ch10_1; import io.netty.bootstrap.ServerBootstrap; import io ...