使用epollet网络模型写了一个简单的httpserver,通过apachebench(ab)压测时,遇到几个问题,网上搜了下,大把的以讹传讹,研究了下源码,终于把问题弄明白了,今天鄙人第一次在网上写博,公布下解决方案,以帮助后来者少走弯路。
问题1:apr_socket_recv: Connection timed out (110)
问题分析:从ab.c源码可以看到,如果没有设置-r参数,ab在socket接收到错误后,apr_err会使用exit即刻退出。
解决方案:ab使用时加上-r参数,如:ab -r -n200000 -c10000
附ab.c的部分源码(apache/support/ab.c,apache版本不同,这里的源代码行数可能不同)
1398 if (recverrok) {
1399 bad++;
1400 close_connection(c);
1401 if (verbosity >= 1) {
1402 char buf[120];
1403 fprintf(stderr,"%s: %s (%d)\n", "apr_socket_recv", apr_strerror(status, buf, sizeof bu f), status);
1404 }
1405 return;
1406 } else {
1407 apr_err("apr_socket_recv", status);
1408 }
问题2:apr_socket_recv: Connection reset by peer (104)
解决方案同问题1,在遇到错误时,加-r参数,避免即刻退出
问题3:apr_pollset_poll: The timeout specified has expired (70007)
问题分析:从ab.c源码可以看到,在socket等待server的响应超过超时时间(-s可指定,未指定默认30s),则调用apr_err退出。
解决方案:找到如下红色标识的两行代码,注释掉,重新编译apache/support目录(可单独support,无需重新编译apache)
1755 do {
1756 status = apr_pollset_poll(readbits, aprtimeout, &n, &pollresults);
1757 } while (APR_STATUS_IS_EINTR(status));
1758 if (status != APR_SUCCESS)
1759 apr_err("apr_pollset_poll", status);
最后附上PO主自己写的简单http server在访问1K大小静态文件时使用ab并发10000情况下的压测结果,TPS达到9500+。
Concurrency Level: 10000
Time taken for tests: 208.878 seconds
Complete requests: 2000000
Failed requests: 9498
(Connect: 0, Receive: 3166, Length: 3166, Exceptions: 3166)
Total transferred: 3340714993 bytes
Total body sent: 3406000000
HTML transferred: 3131046688 bytes
Requests per second: 9574.96 [#/sec] (mean)
Time per request: 1044.390 [ms] (mean)
Time per request: 0.104 [ms] (mean, across all concurrent requests)
阅读(9711) | 评论(1) | 转发(0) |