Apache Benchmark修改,支持发送不同数据包
2015-06-13 14:20
621 查看
起因是,工作中一些接口需要性能测试,首先考录本地代码的测试工具,因为测试工具本身的性能开销很小,更加合适,然后AB(Apache Benchmark)简单便捷,但是,AB的-p参数只支持读取一个post数据文件,然后重复发送一样的内容,在我的接口处理同样数据时,只有第一次是真正的新增,而后只是快速返回之前的数据,所以这并不能体现新增接口的性能。
为了寻求使用AB实现每次发送不同的POST数据,翻了下源代码。
AB的实现很简单,根据不同参数拿到不同的值,直接存到一堆全局变量里面。test函数负责读取一些全局变量,创建socket连接,使用非阻塞的socket,同时创建C个连接,通过-c参数指定的并发数就是这里的连接数,这里并不是多线程去请求,因为是非阻塞,所以直接循环connect即可实现并发。然后用异步的epoll方式取处理封装好的Http请求header及body。发送的次数N由参数-n指定。请求完成之后output_html_results函数或output_results函数计算请求时间之类的结果并输出。
下面来分析下-p参数,-p指定一个文件,这个文件存有Http请求的body。open_postfile函数读取文件内容。apr_file_open,apr_file_info_get,apr_file_read_full是APR库里面封装的文件操作系列函数。AB中用apr_file_read_full读取整个文件内容并存储在全局变量postdata(buffer containing data from postfile)中,然后发送的时候将其拼装到Http的Body通过Socket发送给url。
根据以上-p的原理,只要自己来指定一种格式,读取包含多个Http请求Body的文件后,解析出多个Body,组成多个Http包,然后每次发送不同的Http包即可。所以改动点主要有3个:
1. 添加一套全局变量,其中request_multi表式一个二位数组,包含不同的Http包,制定-m参数表式发送多重post请求
2. 添加读取并解析特定格式buffer的状态机
3. 发送不同的buffer与。
在原始代码中,write_request函数中:
这个函数是APR封装的send函数,request是在test函数中预先根据postdata拼装好的Http包buffer,c->rwrote是发送完成偏移量。问题在于,多个不同的buffer需要使用二维数组来存储,然后为了发不同的内容需要每次指定一个数组下标取不同的buffer。上述的write_request,每次调用发送的都是同样的内容。重写另一个wirte_request成本稍微比较大,而且大部分代码会是一模一样的,好在发现了另一个全局变量:started(number of requests started, so no excess),每个buffer发送成功后,这个变量会自增,刚好可以用来当作二维数组下标来用,只要用另一个变量区分以下当前是发送多重Post从而发送request_multi即可。
现在规定的文件格式如下:
其中,count指定当前文件的请求数,实际上-n参数指定的值会被count覆盖。
内存使用的一点分析:
AB本身每个Http包的长度最大2048字节,每次最大请求数50000,按此最大值来算一次读取的文件最大需要内存 2048 * 50000 * 3 == 300M,乘以3因为第一次读取文件存入buffer,第二次解析存入post buffer,第三次post buffer拼装成request buffer。第一次第二次的相当于两次的复制过程,复制完成之后可以直接free掉。不过AB本身的使用场景决定,全部请求发送完成之后进程直接退出,保证其所有内存全部被系统回收。
AB源码是在Apache Httpd的support下的,我用的是Httpd2.4,比2.2的代码整齐一些。
代码(依赖APR):https://github.com/fankux/ApacheBenchmarkMulti
另外,水平有限,欢迎随时拍砖!
为了寻求使用AB实现每次发送不同的POST数据,翻了下源代码。
AB的实现很简单,根据不同参数拿到不同的值,直接存到一堆全局变量里面。test函数负责读取一些全局变量,创建socket连接,使用非阻塞的socket,同时创建C个连接,通过-c参数指定的并发数就是这里的连接数,这里并不是多线程去请求,因为是非阻塞,所以直接循环connect即可实现并发。然后用异步的epoll方式取处理封装好的Http请求header及body。发送的次数N由参数-n指定。请求完成之后output_html_results函数或output_results函数计算请求时间之类的结果并输出。
下面来分析下-p参数,-p指定一个文件,这个文件存有Http请求的body。open_postfile函数读取文件内容。apr_file_open,apr_file_info_get,apr_file_read_full是APR库里面封装的文件操作系列函数。AB中用apr_file_read_full读取整个文件内容并存储在全局变量postdata(buffer containing data from postfile)中,然后发送的时候将其拼装到Http的Body通过Socket发送给url。
根据以上-p的原理,只要自己来指定一种格式,读取包含多个Http请求Body的文件后,解析出多个Body,组成多个Http包,然后每次发送不同的Http包即可。所以改动点主要有3个:
1. 添加一套全局变量,其中request_multi表式一个二位数组,包含不同的Http包,制定-m参数表式发送多重post请求
2. 添加读取并解析特定格式buffer的状态机
3. 发送不同的buffer与。
在原始代码中,write_request函数中:
e = apr_socket_send(c->aprsock, request + c->rwrote, &l);
这个函数是APR封装的send函数,request是在test函数中预先根据postdata拼装好的Http包buffer,c->rwrote是发送完成偏移量。问题在于,多个不同的buffer需要使用二维数组来存储,然后为了发不同的内容需要每次指定一个数组下标取不同的buffer。上述的write_request,每次调用发送的都是同样的内容。重写另一个wirte_request成本稍微比较大,而且大部分代码会是一模一样的,好在发现了另一个全局变量:started(number of requests started, so no excess),每个buffer发送成功后,这个变量会自增,刚好可以用来当作二维数组下标来用,只要用另一个变量区分以下当前是发送多重Post从而发送request_multi即可。
现在规定的文件格式如下:
count\n post1\n ===> post2\n ===> postn\n ...
其中,count指定当前文件的请求数,实际上-n参数指定的值会被count覆盖。
内存使用的一点分析:
AB本身每个Http包的长度最大2048字节,每次最大请求数50000,按此最大值来算一次读取的文件最大需要内存 2048 * 50000 * 3 == 300M,乘以3因为第一次读取文件存入buffer,第二次解析存入post buffer,第三次post buffer拼装成request buffer。第一次第二次的相当于两次的复制过程,复制完成之后可以直接free掉。不过AB本身的使用场景决定,全部请求发送完成之后进程直接退出,保证其所有内存全部被系统回收。
AB源码是在Apache Httpd的support下的,我用的是Httpd2.4,比2.2的代码整齐一些。
代码(依赖APR):https://github.com/fankux/ApacheBenchmarkMulti
另外,水平有限,欢迎随时拍砖!
相关文章推荐
- Apache Isis 1.4.0 发布,领域驱动开发框架
- Linux快速构建apache web服务器
- Awstats处理多apache日志
- 安装perl模块小窍门
- PHP+Apache在Windows 9x下的安装和配置
- Apache服务器配置全攻略
- Apache Web让JSP“动”起来
- Linux Apache+MySQL+PHP
- 建立Apache+PHP+MySQL数据库驱动的动态网站
- apache 环境下 php 的配置注意事项
- 在RedHat下安装apache jserv 1.1.2方法
- windows中PHP5.2.14以及apache2.2.16安装配置方法第1/2页
- 在Windows XP下安装Apache+MySQL+PHP环境
- 效率高的Javscript字符串替换函数的benchmark
- 解析阿里云ubuntu12.04环境下配置Apache+PHP+PHPmyadmin+MYsql
- apache rewrite防盗链三例
- Apache 配置详解(最好的APACHE配置教程)
- Apache+php+mysql在windows下的安装与配置(图文)第1/2页
- apache rewrite_module模块使用教程
- Apache rewrite重写规则的常见应用