apache的web服务器自带的ab.exe服务器http压力测试用法

时间:2022-12-05 04:49:44


http://blog.sina.com.cn/s/blog_51a7b40e010106b7.html


APACHE的bin目录下。

格式.ab [options] [http://]hostname[:port]/path
参数
-nrequests    Number of requests to perform
//在测试会话中所执行的请求个数。默认时,仅执行一个请求
-c concurrency Number of multiple requests to make
//一次产生的请求个数。默认是一次一个。
-t timelimit   Seconds to max. wait for responses
//测试所进行的最大秒数。其内部隐含值是-n50000。它可以使对服务器的测试限制在一个固定的总时间以内。默认时,没有时间限制。
-ppostfile    File containing data to POST
//包含了需要POST的数据的文件.
-T content-type Content-type header for POSTing
//POST数据所使用的Content-type头信息。
-v verbosity   How much troubleshooting info to print
//设置显示信息的详细程度 - 4或更大值会显示头信息,3或更大值可以显示响应代码(404, 200等), 2或更大值可以显示警告和其他信息。 -V显示版本号并退出。
-w             Print out results in HTML tables
//以HTML表的格式输出结果。默认时,它是白色背景的两列宽度的一张表。
-i             Use HEAD instead of GET
// 执行HEAD请求,而不是GET。
-x attributes   String to insertas table attributes
//
-y attributes   String to insertas tr attributes
//
-z attributes   String to insertas td or th attributes
//
-C attribute   Add cookie, eg. ‘Apache=1234. (repeatable)
//-C cookie-name=value对请求附加一个Cookie:行。 其典型形式是name=value的一个参数对。此参数可以重复。
-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.
//-P proxy-auth-username:password对一个中转代理提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即,是否发送了401认证需求代码),此字符串都会被发送。
-X proxy:port   Proxyserver andport 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.
-gfilename    Output collected data to gnuplot format file.
-efilename    Output CSV file with percentages served
-h             Display usage information (this message)
//-attributes 设置 属性的字符串.缺陷程序中有各种静态声明的固定长度的缓冲区。另外,对命令行参数、服务器的响应头和其他外部输入的解析也很简单,这可能会有不良后果。它没有完整地实现HTTP/1.x; 仅接受某些’预想’的响应格式。 strstr(3)的频繁使用可能会带来性能问题,即,你可能是在测试ab而不是服务器的性能。

参数很多,一般我们用 -c 和 -n 参数就可以了. 例如:

打开cmd,输入 以下代码。

cd C:\Apache2.2\bin

ab -n 1000 -c 100 http://zf.guqin.com/index/index

----------------------------------------------------------------------------------------------------------------------------------------、

压力测试中JVM内存暴涨原因分析实战 采用apache ab

工作之中写了个小的Web应用,类似于脚手架的demo应用,用spring搭的,在tomcat里运行。

程序写完了,想看看能承受多大的访问压力,遂开始进行压力测试。没有用复杂的loadrunner压测,采用了一个简单的url压测工具http_load,只是单纯地用来压某个url的并发访问。

压测环境介绍:

????? 一台普通的linux服务器,双核,4G内存。

?????tomcat启动内存和最大内存设置为1G,最大处理线程数为默认的200个,http_load模拟200个用户并发访问,持续10分钟

使用lambdaprobe监控tomcat的运行情况,发现jvm内存一直在上涨,从1%增长到90%,最后居然内存溢出了!才压了10分钟而已,感觉到非常奇怪。

于是决定看看jvm的gc日志,在catalina.sh文件中加入jvm参数:

-Xloggc:gclog.vgc -XX:+PrintGCTimeStamps-XX:-PrintGCDetails -XX:+UseConcMarkSweepGC

观察输出的日志文件,发现将近每半秒进行一次GC操作,但是每秒内存还是在均匀上涨1M左右

于是想看看到底是哪些内存对象占用了过多的内存:

???? 首先找出tomcat进程ID,然后运行如下命令,获得其JVM内存对象的占用情况

?1:???????1040160???????33285120??java.util.concurrent.ConcurrentHashMap$Segment?????2:???????1040354???????24968496??java.util.concurrent.locks.ReentrantLock$NonfairSync?????3:????????192962???????23240344??[C?????4:?????????32123???????17892336??[B?????5:???????1040287???????17859608??[Ljava.util.concurrent.ConcurrentHashMap$HashEntry;??

可以看到,java.util.concurrent.ConcurrentHashMap$Segment对象实例最多,且占用了大量的内存。当前JVM内存占用总量为155M,ConcurrentHashMap$Segment,ConcurrentHashMap$HashEntry,java.util.concurrent.locks.ReentrantLock加起来占用了差不多一半的内存!~

回头查看自己的程序代码,看是否有使用ConcurrentHashMap对象,或者滥用该对象的情况。

检查后发现自己程序并没有使用ConcurrentHashMap对象!~很郁闷,到底是哪里在大量的对ConcurrentHashMap进行操作,使得该Map越来越大呢?

经过网上搜索,发现一个比jconsole还强大的jvm监控工具,也是sun推出的,叫做,下载下来该工具后,还可以下载几个插件,丰富其监控功能,甚为好用。

附上一个监控图,非常详细和动态的显示了Eden,S0,S1,Old,Perm区的内存占用情况

由于要分析出到底哪里的ConcurrentHashMap对象被不断的put操作,使其异常庞大,于是首先用visualvm把heapdump出来。在Monitor标签页中有一个Heap Dump按钮,点击就是,该操作会把当前的jvm内存情况导出到一个文件中。

visualvm可以分析dump文件,但是我使用之后感觉非常慢。然后就是另一个工具登场了,HeapAnalyzer ,用该工具来分析dump出的文件。该工具下载下来后为jar文件,直接java -jar运行之。

找出size最大的java.util.concurrent.ConcurrentHashMap$Segment对象:

发现该对象的父对象是org.apache.catalina.session.StandardManager.

查看tomcat源代码发现该类继承自ManagerBase,ManagerBase中果然有一个成员变量为ConcurrentHashMap!

protected?Map<String,?Session>?sessions?=?new?ConcurrentHashMap<String,?Session>();??

该对象存储的就是大名鼎鼎的容器session。

原来,http_load模拟的Url请求没有附带cookie和url重写,也就没有JSESSIONID信息,导致每一个请求,容器都会创建一个新的session。短短10分钟内200个线程并发访问,导致session暴涨。

但是我查看了自己的程序代码,并没有对session进行操作,那么容器是在何时创建新的session呢?

谜底就在于返回的JSP页面。学过jsp/servlet都知道,jsp页面默认有个session变量,查看tomcat目录下的jsp编译后的文件会发现如下代码:

1.response.setContentType("text/html");??
2.pageContext = _jspxFactory.getPageContext(this, request,response,??
3.????????? null, true, 8192, true);??
4._jspx_page_context = pageContext;??
5.application = pageContext.getServletContext();??
6.config = pageContext.getServletConfig();??
7.session = pageContext.getSession();??
8.out = pageContext.getOut();??
9._jspx_out = out;?

getSession()方法会返回当前请求的JSESSIONID对应的session,如果没有就新创建一个session返回。

为了验证该问题,我在返回的JSP页面里加入了

<%@page?session="false"%>??

?不使用session,再次进行压力测试,结果印证了我的想法。

下面是没加session="false"和加上了的两种情况的内存增长图,作为对比,结果非常明显:

这次事件也告诉我不能随便选择测试工具,因为真实用户访问都是会附带cookie信息的,不会出现每个请求都需要创建session的情况。

附:

tomcat使用ConcurrentHashMap来存储session,在并发访问的情况下有更好的性能。有关更多session知识,可以参考:

???? http://java.chinaitlab.com/base/802833.html

???? http://xuehu2009.javaeye.com/blog/524303


例子

D:\apache2\Apache2\bin>ab -n 100 -c 30 http://blog.donews.com/zzw45/
This is ApacheBench, Version 2.0.41-dev <$Revision:1.121.2.12 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/

Benchmarking blog.donews.com (be patient).....done


ServerSoftware:       Microsoft-IIS/6.0
ServerHostname:       blog.donews.com
ServerPort:           80

DocumentPath:         /zzw45/
DocumentLength:       72372 bytes

ConcurrencyLevel:     30
Time taken for tests:   89.734375seconds
Completerequests:     100
Failedrequests:       0
Writeerrors:          0
Totaltransferred:     7277216 bytes
HTMLtransferred:      7237200 bytes
Requests persecond:    1.11[#/sec] (mean)
Time perrequest:      26920.313 [ms] (mean)
Time perrequest:      897.344 [ms] (mean, across all concurrent requests)
Transferrate:         79.19 [Kbytes/sec] received

Connection Times (ms)
             min mean[+/-sd] median  max
Connect:      31  31  1.5    31     46
Processing: 2625 18634 18972.611703   87015
Waiting:      62 892 1958.7   296   9640
Total:      2656 18665 18972.5 11734  87046

Percentage of the requests served within a certain time(ms)
50% 11734
66% 14609
75% 19890
80% 24718
90% 50718
95% 62515
98% 81343
99% 87046
100% 87046 (longest request)