网站首页 > 资源文章 正文
首先呢,先复习一下关于统计QPS中用到到一个请求模型。在之前的两篇讨论性能测试误差的文章性能测试误差分析文字版-上、性能测试误差分析文字版-下中,我画了一个简单的请求时间模型。
计算模型
如图所示,这是单个线程单个请求的耗时简易模型,分成三部分:请求前(对应before)、请求与响应(对应request and response)和请求后(对应after)。其中T代表三个部分的总时间,rt代表了请求与响应的时间。
请求计算模型
Java NIO
Java NIO有两种解释:一种叫非阻塞IO(Non-blocking I/O),另一种也叫新的IO(New I/O),其实是同一个概念。NIO是一种基于通道和缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内存(区别于JVM的运行时数据区),然后通过一个存储在java堆里面的DirectByteBuffer对象作为这块内存的直接引用进行操作。这样能在一些场景显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。
以上内容摘要,我的理解也不十分透彻。PS:我更建议有能力的搜一搜,了解一下也是好的。
下面我分享一下Java NIO在HTTP协议接口测试中的应用。
缘由
在上图第二部分中,请求和响应占据了整个部分。如果我们将这部分再细分,那么可以分成三个部分:发出请求、等待响应、接收响应。Java NIO在接口测试中的应用就在等待响应和接收响应这一部分。如果我们使用一种技术,将发出请求之后,等待响应和接收响应这个过程交给另外线程处理,又不影响两者之间的关系,那么我们就可以不断地发出请求,提高客户端性能而又不影响我们接收响应,进行业务验证。
对于那些响应时间比较长的接口来说。这样的处理结果能够极大的提升客户端发送请求的速率。对于线程数一定的情况下,由单个客户端发起的压力也会成倍的增加。经过本人在本地进行单线程模拟测试。(这个倍数大约在30倍左右。可见Java NIO的性能提升有多强。当然在实际的更大压力的性能测试中,这个倍数会降低很多。)
HttpClient应用
HttpAsyncClient则使用Java NIO的异步非阻塞事件驱动I/O模型,实现了真正意义的异步调用,使用HttpAsyncClient我们需要引入其专门的包
之前我有写过文章:HTTP异步连接池和多线程实践,只不过现在在看当时显得特别的字呢,对于http client异步客户端也有点儿理解不透彻,特别是对于callback函数的应用。
核心方法如下:
@Override
public Future<HttpResponse> execute(
final HttpUriRequest request,
final FutureCallback<HttpResponse> callback) {
return execute(request, HttpClientContext.create(), callback);
}
第一个是参数请求对象,第二个参数是回调函数。其中我之前常用的请求对象org.apache.http.client.methods.HttpRequestBase,具体实现代码摘要public abstract class HttpRequestBase extends AbstractExecutionAwareRequest implements HttpUriRequest, Configurable。
下面是我经过一些资料的查证,重新写了一下。Http client异步客户端的使用方法的封装。
不管不顾
这个方法只负责把请求发出去,至于响应一律不管。这里据我查证,callback如果传null的话,在处理响应的时候会直接释放连接等相关资源。
/**
* 异步发送请求
*
* @param request
*/
public static void executeSync(HttpRequestBase request) {
ClientManage.httpAsyncClient.execute(request, null);
}
异步打印日志
通过一个简单的日志打印功能实现FutureCallback,来实现异步响应结果的解析和日志打印功能。
/**
* 异步请求,打印日志
*
* @param request
* @param response
*/
public static void executeSyncWithLog(HttpRequestBase request) {
ClientManage.httpAsyncClient.execute(request, logCallback);
}
/**
* 异步请求打印日志的callback
*/
public static final FutureCallback<HttpResponse> logCallback = new FutureCallback<HttpResponse>() {
@Override
public void completed(HttpResponse httpResponse) {
HttpEntity entity = httpResponse.getEntity();
String content = getContent(entity);
logger.info("响应结果:{}", content);
}
@Override
public void failed(Exception e) {
logger.warn("响应失败", e);
}
@Override
public void cancelled() {
logger.warn("取消执行");
}
};
异步解析响应
这里我引入了第二个参数com.alibaba.fastjson.JSONObject,用来保存解析响应,之所以加上这个,用来异步保存响应结果,用来业务验证。
/**
* 异步请求,返回响应,引入第二个参数{@link JSONObject}
*
* @param request
* @param response
*/
public static void executeSyncWithResponse(HttpRequestBase request, JSONObject response) {
ClientManage.httpAsyncClient.execute(request, new FunTester(response));
}
/**
* 异步请求,异步解析响应的FutureCallback实现类
*/
private static class FunTester implements FutureCallback<HttpResponse> {
public FunTester(JSONObject response) {
this.response = response;
}
JSONObject response;
@Override
public void completed(HttpResponse result) {
HttpEntity entity = result.getEntity();
String content = getContent(entity);
response = JSON.parseObject(content);
}
@Override
public void failed(Exception e) {
logger.warn("响应失败", e);
}
@Override
public void cancelled() {
logger.warn("取消执行");
}
}
- httpAsyncClient和HttpClient性能对比,以及这三个方法的性能比较。后续我会进行对比测试。原因是本地服务响应太快,无法体现差异。
猜你喜欢
- 2024-09-26 如何避免重复提交?分布式服务的幂等性设计
- 2024-09-26 聊聊如何实现一个带幂等模板的Kafka消费者
- 2024-09-26 Docker 安装 Kibana(DOCKER 安装UNTUNTU 图形界面 装不上)
- 2024-09-26 「优雅代码」03-optional杜绝空指针异常
- 2024-09-26 Mybatis plus通用字段自动填充的最佳实践总结
- 2024-09-26 不吹牛逼,撸个注解有什么难的(切记不吹牛)
- 2024-09-26 ElasticSearch入门一:入门安装和索引基本操作
- 2024-09-26 如何优雅地记录操作日志?(如何优雅地记录操作日志)
- 2024-09-26 使用Java8改造出来的模板方法真的是yyds
- 2024-09-26 java利用枚举与数据库交互(java利用枚举与数据库交互方式)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- 电脑显示器花屏 (79)
- 403 forbidden (65)
- linux怎么查看系统版本 (54)
- 补码运算 (63)
- 缓存服务器 (61)
- 定时重启 (59)
- plsql developer (73)
- 对话框打开时命令无法执行 (61)
- excel数据透视表 (72)
- oracle认证 (56)
- 网页不能复制 (84)
- photoshop外挂滤镜 (58)
- 网页无法复制粘贴 (55)
- vmware workstation 7 1 3 (78)
- jdk 64位下载 (65)
- phpstudy 2013 (66)
- 卡通形象生成 (55)
- psd模板免费下载 (67)
- shift (58)
- localhost打不开 (58)
- 检测代理服务器设置 (55)
- frequency (66)
- indesign教程 (55)
- 运行命令大全 (61)
- ping exe (64)
本文暂时没有评论,来添加一个吧(●'◡'●)