ab源码分析 (2013-07-12 13:00:06) http://blog.sina.com.cn/s/blog_999d1f4c0101e18f.html
2015-09-07 20:45
561 查看
ab源码分析
(2013-07-12 13:00:06)转载▼
标签:
| 分类: 工具 |
ab(apache bench)是web服务器APACHE自带的压力测试工具。它通过模拟多个客户端同时对web服务器发起请求,对WEB服务器的并发性能进行测试。对于一般的服务器端程序,ab也提供了一种并发性测试的思路。本文将对ab的关键逻辑进行分析。ab的源码可以从http://code.google.com/p/apachebench-standalone/下载。
ab的使用说明如下:
Usage: ab [options] [http[s]://]hostname[:port]/path
Options are:
-n requests Number of requests to perform
-c concurrency Number of multiple requests to make
-t timelimit Seconds to max. wait for responses
-b windowsize Size of TCP send/receive buffer, in bytes
-p postfile File containing data to POST. Remember also to set -T
-u putfile File containing data to PUT. Remember also to set -T
-T content-type Content-type header for POSTing, eg.
'application/x-www-form-urlencoded'
Default is 'text/plain'
-v verbosity How much troubleshooting info to print
-w Print out results in HTML tables
-i Use HEAD instead of GET
-x attributes String to insert as table attributes
-y attributes String to insert as tr attributes
-z attributes String to insert as td or th attributes
-C attribute Add cookie, eg. 'Apache=1234. (repeatable)
-H attribute Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
Inserted after all normal header lines. (repeatable)
-A attribute Add Basic WWW Authentication, the attributes
are a colon separated username and password.
-P attribute Add Basic Proxy Authentication, the attributes
are a colon separated username and password.
-X proxy:port Proxyserver and port number to use
-V Print version number and exit
-k Use HTTP KeepAlive feature
-d Do not show percentiles served table.
-S Do not show confidence estimators and warnings.
-g filename Output collected data to gnuplot format file.
-e filename Output CSV file with percentages served
-r Don't exit on socket receive errors.
-h Display usage information (this message)
-Z ciphersuite Specify SSL/TLS cipher suite (See openssl ciphers)
-f protocol Specify SSL/TLS protocol (SSL3, TLS1, or ALL)
其中,最常用的参数为-n和-c,这两个参数分别指定了向服务器发起的请求数量和并发程度。其它参数则主要针对HTTP请求和响应的格式以及ab的输出方式。
ab的实现依赖于APR(Apache Portable Runtime)库,该库对unix平台编程接口进行了统一的封装和扩展,但从名子可以很容易的看出它们之间的对应关系。本文不再赘述。ab在模拟并发访问时并没有使用多线程,而是使用了一种异步connect+epoll的方式来实现,下文主要对这一过程进行分析。
我们从ab的main方法看起,该方法主要对参数进行解析并设定了一些代表参数的全局变量,最后分别调用了以下方法:
copyright();
test();
apr_pool_destroy(cntxt);
即ab的主要逻辑包含在test方法中。test方法首先进行了一些全局的初始化工作。其中,最重要的一个数据结构是数组struct connection con[c],代表同时存在的c个客户端连接。struct connection的结构如下:
struct connection {
apr_pool_t *ctx;
apr_socket_t *aprsock;
apr_pollfd_t pollfd;
int state;
apr_size_t read;
apr_size_t bread;
apr_size_t rwrite, rwrote;
apr_size_t length;
char cbuff[CBUFFSIZE];
int cbx;
int keepalive;
int gotheader;
apr_time_t start,
connect,
endwrite,
beginread,
done;
int socknum;
int port;
#ifdef USE_SSL
SSL *ssl;
#endif
};
test方法首先调用start_connect开始c个初始的连接
for (i = 0; i < concurrency; i++) {
con[i].socknum = i;
start_connect(&con[i]);
}
start_connect首先创建一个socket端口并将其设置为非阻塞,这样调用connect时就会立即返回EINPROGRESS错误,但TCP三步握手仍在后台进行。通过这种方式,就可以同时发起多个连接,从而模拟多个客户端请求服务器的场景。start_connect的主要逻辑如下:
re = apr_connect(sock);
if(re == EINPROGRESS){
将sock加入到epoll的监控列表中,等待连接完成
}
else if(re == SUCCESS){
连接已完成,调用write_request发出请求,后文将介绍
}
else{
报错
}
返回test 方法,在创建完成初始的连接之后,test开始使用epoll来监听连接完成、有新的响应数据等事件并进行处理:
do{
do{
status = apr_pollset_poll(readbits, aprtimeout, &n, &pollresults);
}while (status == EINTR);
for(I = 0;I < n;++i){
……
rv = next_fd->rtnevents; //取epoll事件
if ((rv & APR_POLLIN) || (rv & APR_POLLPRI) || (rv & APR_POLLHUP))
read_connection(c); //读服务器端的响应数据
if ((rv & APR_POLLERR) || (rv & APR_POLLNVAL)) {
出错,此时调用start_connect重试连接
}
if(rv & ARP_POLLOUT){ //可写,如果连接完成则返回可写事件
if(处于CONNECTING状态){
rv = apr_socket_connect(c->aprsock, destsa); //此时再连接应直接返回
if (rv != APR_SUCCESS) {
重新调用start_connect开始连接
}
else{
//连接成功
调用write_request发送请求
}
}
}
}
}while(未完成)
上文中提到的write_request和read_connection分别为向服务器发出请求以及从服务器读取响应数据的方法。其中write_request方法会将预先创建好的http请求的内容一次性发送出去;而read_connection则尝试读取、解析服务器端响应并在读取到EOF后调用close_connection方法关闭当前连接。
最后, close_connection方法除了关闭socket端口、记录结果外,如果请求数未达到要求时还会复用要关闭的struct connection,重新调用start_connect发起连接请求,从而推进测试任务。
在一般的操作系统中,单个进程能够新建的线程数量是有限的。通过使用异步connect的方式代替多线程,ab可以提高客户端能够达到的并发程度,从而提高测试能力。虽然ab本身是针对http服务器的测试工具,但这种设计可以被用来对任何服务器端程序进行并发性测试。
相关文章推荐
- apache ab 输出结果详细解析(源码分析) http://my.oschina.net/lubia/blog/177186
- Cocos2dx引擎笔记——HttpClient session
- TestUrlHttpConnection
- TCP/IP,http,socket,长连接,短连接——小结。
- Cocos2dx引擎笔记——如何使用HttpClient
- 快速Android开发系列网络篇之Retrofit, Retrofit OKHttp GSON
- CentOS下使用tcpdump网络抓包用
- linux安装apache的纠结过程 http://www.cnblogs.com/fnng/archive/2012/08/30/2662984.html
- TCP标志位之RST
- 网络编程
- ioS开发之网络--网络基础概况
- iOS开发之网络--服务器配置
- <meta http-equiv="refresh" content="0; url=">什么意思?
- android手机抓wireshark包的步骤-tcpdump
- android菜鸟进阶之路—— HttpURLConnection 的实例
- Python网络资源及常见库
- Linux 安装 httpd2.4.16
- 数据存储(sharedPreferences,内部存储,外部存储,SQLite数据库,网络存储)
- linux网络服务器笔记
- Android的五大存储方式:SharedPreferences、内部存储、外部存储、SQLite和网络存储