Jmeter使用指南

原贴地址:http://hi.baidu.com/%D5%C5%B9%DA%C1%D6/blog/item/084298827b5685bd6c8119c9.html

JMeter是Apache组织的绽开源代码项目,它是法力和性测试的工具,100%底用java实现,最新的版是1.9.1,大家可以到http://jakarta.apache.org/jmeter/index.html下载源代码和查看相关文档。

1 JMeter作用领域

JMeter可以用于测试静态或者动态资源的习性(文件、Servlets、Perl脚本、
java对象、数据库和查询、ftp服务器或者其它的资源)。JMeter用于模拟在服务器、网络或其它对象及附加高负载以测试他们提供劳动的被压能
力,或者分析他们提供的服务以不同负载条件下的究竟性能情况。你可以用JMeter提供的图形化界面分析性能指标或者以青出于蓝负荷情况下测试服务器/脚本/对象
的行事。

2 使用JMeter测试Web应用

连接下的章节里,作者用详细的演示如何运用JMeter来测试Web应用的整体过程。

2.1 测试环境

笔者采取了Tomcat作为Web服务器进行测试,被测试的内容是一个jsp文件与一个
servlet,jsp文件调用JavaBean、打印相关消息,servlet接受用户参数、调用javabean、输出相关信息。详细的内容要参见作
者提供的JMeter.war的情。

2.2 安装启动JMeter

世家可以到通过http://apache.linuxforum.net/dist
/jakarta/jmeter/binaries/jakarta-jmeter-1.9.1.zip下载JMeter的release版本,然后以下
载的.zip文件解压缩至C:/JMeter(后面的篇章中将用%JMeter%来引用这目录)目录下。现在,请动%JMeter%/bin下面的
jmeter.bat批处理公事来启动JMeter的可视化界面,下面的劳作都拿当斯可视化界面界面上进行操作。下面的图是JMeter的可视化界面
的屏幕截图。

图片 1

贪图一律: JMeter打开时的屏幕截图

2.3 建立测试计划(Test Plan)

测试计划描述了行测试过程中JMeter的实行进程以及手续,一个一体化的测试计划包括一个还是
者多单线程组(Thread Groups)、逻辑控制(Logic
Controller)、实例产生控制器(Sample Generating
Controllers)、侦听器(Listener)、定时器(Timer)、比较(Assertions)、配置元素(Config
Elements)。打开JMeter时,它曾立一个默认的测试计划,一个JMeter应用之实例只能建立或者打开一个测试计划。现在咱们开填写一
个测试计划的内容,这个测试计划向一个jsp文件与一个servlet发出请求,我们用JMeter模拟五个请求者(也便是五只线程),每个请求者连续
请求两不好,下面的段介绍了详尽的操作步骤。

2.4 增加负载信息设置

马上无异步,我们将通往测试计划中益相关负载设置,是Jmeter知道我们用效法五个请求者,每个请求者在测试过程中老是请求两破。详细步骤如下:

  1. 入选可视化界面中左边树的Test Plan节点,单击右键,选择Add’Thread
    Group,界面右边将见面并发他的装信息框。

  2. Thread Group有三个同负载信息相关的参数:

Number of Threads: 设置发送请求的用户数据

Ramp-up period:
每个请求发生的毕竟时间隔,单位是秒。比如你的呼吁数目是5,而者参数是10,那么每个请求中的间距就是10/5,也就算是2秒

Loop Count: 请求发生的复次数,如果选背后的forever(默认),那么
请求将直接继续,如果不选择forever,而于输入框中输入数字,那么要将再也
指定的次数,如果输入0,那么要将执同一赖。

依据我们演示例子的宏图,我们该将Number of Threads设置也5,Ramp-up
period设置为0(也就是同时起请求),不选着forever,在Loop
Count后面的输入框中输入2,设置后的屏幕截图如下:

图片 2

贪图二:设置好参数的Thread Group。

2.5 增加默认Http属性(可选)

实际的测试工作多次是本着同一个服务器上Web应用进行的,所以Jmeter提供了这般平等种植
设置,
在默认Http属性设置需要被测试服务器的连带属性,以后的http请求设置中就好忽略这些同参数的装,减少设置参数录入的日。我们这里用应用即时
种属性。你得透过下的手续来装默认http属性:

  1. 入选可视化界面中错误边树的Test Plan节点,单击右键,选择Add’config
    element’http request defaults,界面右边将会冒出他的设置信息框。

  2. 默认http属性的主要参数说明如下:

protocal:发送测试请求时利用的情商

server name or ip:被测试服务器的ip地址或者名字

path:
默认的开始位置。比如以path设置为/jmeter,那么富有的http请求的url中还用追加/jmeter路径。

port number: 服务器提供劳务之端口号

俺们的测试计划将对准本机的Web服务器上的Web应用进行测试,所以protocal应该
是http,ip使用localhost,因为这web应用发布的context路径是/jmeter,所以这边的path设置为/jmeter,因为
使用Tomcat服务器,所以port number是8080。设置后的屏幕截图如下:

图片 3

祈求三: 测试计划中应用的默认Http参数

2.6 增加Http请求

今天我们要增加http请求了,他为是咱们测试的始末重点部分。你得由此下面的步子来增加性的http请求:

  1. 当选可视化界面被错误边树之Thread
    Group节点,单击右键,选择Add’sampler’http
    request,界面右边将见面产出他的设置信息框。

2.
异的参数与2.5蒙受介绍的http属性差不多,增加的属性被生发送http时方法的挑三拣四,你可选择吗get或者post。

咱俩现增多有限独http
请求,因为咱们装了默认的http属性,所以与默认http属性中平等的特性不再另行设置。设置后的屏幕截图如下:

图片 4

贪图四:设置好之jsp测试请求

图片 5

希冀五:设置好的Servlet测试请求(带参数)

2.7 增加Listener

充实listener是为着记录测试信息以可以动用Jmeter提供的可视化界面查看测试
结果,里面有某些种植结果分析方法可供应选择,你可因自己习惯的分析道选择不同的结果显示方式,我们这边运用表格的款型来查看和分析测试结果。你可通
过下面的步子来充实listener:

  1. 当选可视化界面被左边树之Test
    Plan节点,单击右键,选择Add’listener’view result in
    table,界面右边将会见现出他的安装信息及结果显示框。

2.
君得设置界面上面的filename属性设置以测试结果保存至某文件中界面下面用使表格显示测试结果,表格的率先列sampleno显示请求执行之
顺序和号码,url显示请求发送的目标,sample-ms列显示这要完成耗费的年月,最后之success列显示改请求是否成实施。界面的极致下
你还得观看有些统计信息,最关切的相应是Average吧,也就算是呼应的平分日。

2.8 开始履行测试计划

当今您可以经单击菜单栏run ->
Start开始实行测试计划了。下面就点儿单图是笔者首先差、第二次执行该测试计划的结果图:

图片 6

祈求六:第一破实践后的结果显示

图片 7

图七:第二潮施行的结果显示

世家好看来第一糟糕实施时的几乎个要命时值均来自于jsp
request,这可以通过下面的说辞进行说明:jsp执行前都得吃编译成.class文件。所以亚差的结果才是健康的结果。

3 总结

JMeter用于进行供能或者性质测试,通过动用JMeter提供的供能,我们可可视化的制定测试计划:包括确定采用什么的负荷、测试什么内容、传入的参数,同时,他供了成百上千种植图形化的测试结果显示方式,使我们会简单的起来测试工作及分析测试结果。

正文中,作者根据自己之采取更,详细演示了何等使JMeter来展开Web测试的尽过
程,简单的牵线了JMeter提供测试结果的图形化显示界面中相关参数的意思。希望能帮助大家学会使用JMeter的基本知识,同时,大家可以参照这
过程及JMeter的助文档来落实对java对象、数据库等的测试过程。

参考资料:

JMeter 的用户指南 :
http://jakarta.apache.org/jmeter/usermanual/index.html

工具下载:

  1. tomcat http://jakarta.apache.org/tomcat/index.html

  2. JMeter http://jakarta.apache.org/jmeter/index.html

==========================================
找到另外一首比较好的始末:

JMeter技巧集锦

摘要:
若 用Jmeter开发一个载重测试脚论并无困难, 因为JMeter
提供了长的部件和拖拽风格的操作界面,但是,建立一个类实际负荷的测试脚本还是是起得难度之。其中的一个缘由就是是评判测试质量之一部分参数是令人费解
的,本文可以呢汝解答部分即面的困惑,并就怎样满足响应时间相当测试要求等供了有的指导标准。

改良Jmeter 脚本质量

摘要
    使 用Jmeter开发一个载荷测试脚论并无紧, 因为JMeter
提供了长的部件和拖拽风格的操作界面,但是,建立一个像样实际负荷的测试脚本还是是起自然难度之。其中的一个由就是判测试质量的有些参数是令人费解
的,本文可以啊你解答部分即上面的迷惑,并就什么样满足响应时间等于测试需要等供了有些指导标准。

版权声明:任何获Matrix授权的网站,转载时要务必保留以下作者信息及链接
作者:Chi-Chang
Kung;joson(作者的blog:http://blog.matrix.org.cn/page/joson)
原文:http://www.javaworld.com/javaworld/jw-07-2005/jw-0711-jmeter.html
译文:http://www.matrix.org.cn/resource/article/44/44226_JMeter+tips.html
关键字:JMeter;tips

JMeter 是一个盛的用于负载测试的开源工具,
具有许多行之有效的力量元件,如线程组(thread group), 定时器(timer),
和HTTP 取样 (sampler) 元件。 本文是针对JMeter
用户手册的补充,而且提供了关于用Jmeter的一对法元件开发品质测试脚本的点。

本文同时为讨论了一致件重要的情:在指定了纯正的响应时间要求后,如何来校验测试结果,特别是在采用了置信区间分析这种严峻的统计方法的景象下承诺如何操作。请留心,我只要本文的读者们询问有关Jmeter的基础知识,本文的事例基于Jmeter2。0。3版。

规定一个线程组的ramp-up period
(Determine)

   Jmeter脚本的首先单要素是线程组(Thread
Group),因此首先为我们来回顾一下。
正而图一律所展示,线程组需要安装以下参数:
·线程数量。
·ramp-up period。
·运行测试的次数。
·启动时间:立即或者预定的岁月,如果是后者,线程组所蕴涵的素呢使指定这个起止时间。

图片 8
图 1。 JMeter 线程组(JMeter Thread Group)

每个线程均独立运作测试计划。因此,
线程组常用来效仿并发用户访问。如果客户机没有足够的能力来套较重的负载,可以行使Jmeter的分布式测试功能来由此一个Jmeter控制高来远程控制多只Jmeter引擎完成测试。

参 数 ramp-up period 用于告知JMeter
要于多长时间内建全方位的线程。默认值是0。如果未因定ramp-up period
,也就是说ramp-up period 为零, JMeter 将即刻成立有线程,假设ramp-up
period 设置成T 秒,全部线程数设置成N个, JMeter
将各隔T/N秒建立一个线程。

线程组的大多数参数是休摆自明的,只有ramp-up period有来不便知晓,
因为安设置适当的价并无爱。 首先,如果假定用大量线程的话,ramp-up
period
一般不要设置成碎片。因为要安成碎片,Jmeter将会晤以测试的初步就是建立全线程并当即发送访问请求,这样一来就很轻使服务器饱和,更重要之是碰头隐性
地增加了负荷,这就是意味着服务器将可能过载,不是坐平均访问率高而是坐兼具线程的第一浅面世访问使引起的匪健康的初步访问峰值,可以透过Jmeter
的集合报告监听器看到这种光景。
这种特别不是咱们要之,因此,确定一个靠边的ramp-up period
的条条框框就是是给新开始点击率接近平均点击率。当然,也许要周转有测试来规定合理访问量。

依据相同的原因,过深的ramp-up period
也是无得当的,因为将会晤稳中有降访问峰值的负荷,换句话说,在有些线程还无启动时,初期启动之有线程可能曾经收尾了。

这就是说 么,如何检验ramp-up period
I太小了或极端怪了邪?首先,推测一下平分点击率并用总线程除点击率来计算起的ramp-up
period。 例如,假设线程数为100, 估计的点击率也各级秒10不行,
那么估计的理想ramp-up period 就是 100/10 = 10 秒。
那么,应怎样来提出一个理所当然之估计点击率也?没有呀好办法,必须透过运行一坏测试脚本来获得。

附带,在测试计划(test
plan)中益一个聚众报告监听器,如图2所展示,其中蕴蓄了装有独立的看请求(一个samplers)的平均点击率。第一不善取样的点击率(如http
请求)与ramp-up period 和线程数量密切相关。通过调整ramp-up period
可以假设首涂鸦取样的奠基率接近平均取样的点击率。

图片 9
祈求2 JMeter 聚合报告

其三, 查验一下Jmeter日志(文件位置:JMeter_Home_Directory/bin)
的末尾一个线程开始经常首先只线程是否真正结束了,二者的光阴各异是否正规。

总的说来,是否能确定一个适合的ramp-up time 取决于以下简单长条规则:
·第一个取样器的点击率(hit
rate)是否接近其他取样器的平均值,从而能否避免ramp-up period 过些微。
·在终极一个线程启动时,第一单线程是否在真正结束了,最好双边的时刻如硬着头皮的长,以避免ramp-up
period过那个。

偶然,这片修规则之结论会互相冲突。
这就是意味着无法找到以满足个别久规则之适宜的ramp-up period。
糟糕之测试计划通常会导致这些题目,这是为以如此的测试计划里,取样器将不能够尽量地搜集数据,可能以测试计划执行时太短并且线程会很快的运作了。

用户考虑时(User think
time),定时器,和代理服务器(proxy server)

    在 负载测试着要考虑的之一个首要因素是想时(think time),
也即是在片次于成功之访请求中的中断时间。有多种状挥发导致延迟的来:
用户用时读书文字内容,或者填表,或者搜索正确的链接等。未认真考虑考虑时时会面导致测试结果的失真。例如,估计数值不适用,也就是让测量系统可支
持之最好多用户量(并发用户)看起好像要掉一些抵。

Jmeter提供了一整套底计时器(timer)来学思考时(think
time),但是仍存在一个题目:: 如何规定适合的构思时也?幸运的凡,
JMeter 提供了一个不错的答案:使用 JMeter HTTP 代理服务器(Proxy
Server)元件。

代理服务器会记录在使一个屡见不鲜的浏览器(如FireFox 或 Internet
Explorer)浏览一个web应用时的操作。 另外, JMeter
在笔录操作的还要会建立一个测试计划(test plan)。
这个效应会提供以下便利:
·不必手工建立HTTP 访问请求,
尤其是当要设置有令人乏味的参数时(然而,非英文的参数也许不可知健康工作)
。JMeter 将会见录制包括富含字段(hidden fields)在内的有所情节。
·在变的测试计划中,Jmeter会包含浏览器生成的有的 HTTP
报头,如User-Agent (e。g。, Mozilla/4。0), 或AcceptLanguage (e。g。,
zh-tw,en-us;q=0。7,zh-cn;q=0。3)等。
·JMeter
会根据设置于录制操作的以起部分定时器,其延迟时间是完全依据真人真事的操作来设置的
现 在给咱们来拘禁一下哪安排Jmeter的录制功能。 在JMeter 的控制台上,
在工作台(WorkBench)元件上单击右键,然后择”add the HTTP Proxy Server
“。 注意是当WorkBench 上单击右键而未是以Test
Plan上,因为今天凡设吧记录操作进行布置而非是使运行测试计划。  HTTP Proxy
Server
的贯彻原理就是经过配备浏览器的代理服务器而只要所有的顾请求通过JMeter发送(,因而被Jmeter把访问过程录制下来)。

若果图3所著, HTTP代理服务器(HTTP Proxy
Server)元件的局部参数必须于布置:
·端口(port): 代理服务器的监听端口
·目标控制器(Target Controller):
是代理用于存储生成的数的控制器,默认情况下,, JMeter
将会当时下底测试计划中检索一个记下用的控制器用于存储,此外也得以于下拉菜单中精选随机支配起来存储,通常默认值就好了。
· 分组(Grouping): 确定在测试计划中如何来呢转变的预制构件分组。
有多单挑选,一般可挑选“只存储每个组的率先独样本”,否则,将会晤相录制URLs,包括富含图像和JavaScripts脚本的页面。当然为得以品味
一下默认值“不对样本分组”(”Do not group samples”),来拘禁一下JMeter
建立之原版的测试计划。
·包含模式(Patterns to Include) 和 排除模式(Patterns to Exclude)
:帮助过滤一些请勿待之顾请求。

图片 10
祈求 3。 JMeter 代理服务器(Proxy Server)。

当 你点击开始(Start)按钮时,代理服务器就会见初步记录所领的HTTP
访问请求。当然,在上马记录面前,要首先设置好浏览器的代理服务器设置。在代理服务器元件中好加一个定时器子元件(配置元件),用于告知Jmeter来
在那转的
HTTP请求被活动的加一个定时器。Jmeter会自动将实际的延迟时间存储吗一个为命名为T的Jmeter变量,因此,如果当代理服务器元件里用了
高斯随机定时器,就应以内部的稳定延迟偏移(Constant Delay
Offset)设置项里上上${T}(用于机动引用纪录的延迟时间),如图4所著。这是任何一个节省时间的有益特性。

图片 11
祈求 4。 在代理服务器组建中长一个高斯随意定时器

定时器将会见要相应的之取样器被推迟。
延时的条条框框是,在达成一个看请求被响应并延时了点名的辰晚,下一个让定时器影响之抽样访问请求才见面让发送出。
因此,
你要手工去第一单取样器中自动生成的定时器,因为第一只取样器不需定时器。
当 启动HTTP代理服务器以前,要当测试计划中追加一个线程组(thread
group),在线程组中加进一个录制控制器(recording
controller)用于存储生成的结果。 否则,
生成的预制构件将会给直接助长到工作台里。另外,在录制控制器里添一个HTTP请求默认值元件HTTP
Request Defaults 元件 (是一个配置元件)
也充分要紧,这样Jmeter就无填使用了默认值的字段。
录制好后, 停止HTTP 代理服务器;
在录制控制器元件上单击右键将记录之部件保存也一个文书用于以后用,另外,不要遗忘了还原浏览器的代理服务器设置。

点名响应时间要求并校验结果

    尽管本节内容跟Jmeter不是直接有关,但是Jmeter仍旧是点名响应时间要求以及校验测试结果这点儿单负载测试评价任务互相联系的焦点。


web应用之条件里,响应时间凭借的凡从提交访问请求到相当交HTML结果所消耗的岁月。从技术之角度看,响应时间也答应包括浏览器重绘HTML页面的辰,但
是浏览器一般是一致片就一片地出示如果不是直接展示完整的浑页面,让人感觉响应时间如掉一些。另外,典型的情形是,负载测试工具不会见考虑浏览器的重绘时
间。 因此,
在实际上的特性测试着,我们用考虑上述描述的情,如果无克确信,可以以常规的应时间达到加以一个固定值,如0.5秒。

以下是一样学众所周知的规定相应时间之正统:
·用户用不见面小心到一定量0.1秒的推迟
·少于1秒的推不会见停顿用户的正规思维, 但是有些延会叫用户注意到
·延迟时间少于10秒,用户会持续守候响应
·延迟时间超过10秒后,用户用会见放弃并开其他操作

这些阀值很出名并且一般不见面转移,因为是关乎人类的感知特性的。
所以要根据这些规则来设置响应时间要求,也亟需适度调整为适应实际运用。例如,亚马逊公司(Amazon.com)
的主页也按照了以上规则,但是由还讲求于风格上的相同,所以当应时间及生一些损失。

初一看,好像有三三两两种植不同的道来规定相应时间要求:
·平均响应时间(Average response time )
·绝对响应时间(Absolute response time);即,
所有的响应时间得低于某平阀门值

点名平均响应时间比较简单一些(straightforward),但是出于数量变化的打扰,这个需要数难以实现。为什么取样中之20%之应时间而比平均值高3倍增以上也?请小心,JMeter
计算平均响应时间和图片结果监视器中之正统不是是平等的。
一头, 对绝对响应时间要求过于苛求是不实际的。
如果单单有0。5%的抽样不能够透过测试该怎么处置?如果再测一赖,又会发出酷十分之转变。
幸运的凡, 使用置信区间(confidence
interva)分析这种专业的统计方法可以照顾到取样变化之熏陶。
于连续展开前,让我们先是想起一些核心的统计学知识。

核心极限定理(The central limit theorem)
  中心极限定理表明要完全的遍布有一个等分值μ和标准偏差σ,那么对一个十分大的n(>30),其取样平均值的遍布将看似受正态分布,其平均值μmean
= μ ,标准不是σmean = σ/√n。
瞩目取样平均值的分布是正态的,而抽样自身的布不必是正态的。也就是说要反复运行测试脚论则测试结果的平分响应时间将会晤是正态的。

祈求 5 和图 6 分别显示了少数只正态分布。 在此地横坐标是采样响应时间之均值,
总体的均值为调到坐标的原点(shifted so the population mean is at the
origin)。 图5 表明90%底流年里,采样均值位于±Zσ的间距里(percent of the
time, the sampling means are within the interval ±Zσ,),这里的Z=1.645
和 σ 是标准不是。 图 6 表明了99%的景象下之图景这时的Z=2.576。
在加的票房价值下,如90%,我们可以看相应的Z呈现正态曲线,反之亦然。

图片 12
Figure 5。 Z value for 90 percent
  

图片 13
Figure 6。 Z value for 99 percent

每当
相关资料被所列的是可资正态曲线计算的有网站。在这些网站,我们得算随意的相对区间内的票房价值(如,-1.5
< X < 1.5)或者在一个凑的区域(cumulated area)内 ,(如, X <
1.5)。 也可于下边的表中得到近似值。

申 1。 对应于给定的置信区间(confidence
interval)的正式不是范围(Standard deviation range)
图片 14

说明 2。 对应于给定的正统不是范围(Standard
deviation)的置信区间(confidence interval)
图片 15

置信区间(Confidence interval)
    置 信区间(confidence interval)的概念是[抽样平均值- Z*σ/√n,
取样平均值+ Z*σ/√n]。 例如,如果置信区间(概率)是90%, 经查找可知Z
值是1。645, 于是置信区间就是 [抽样平均值- 1。645*σ/√n, 取样平均值+
1。645*σ/√n], 这意味着当90%的时间里, 总体平均值(population
mean)(是未知之) 会落入这个置信区间内。也就是说,
我们的测试结果是甚近乎的。 如果 σ(标准不是)
更要命组成部分,置信区间也会另行不行,这就算表示置信区间的上限就见面又可能会见穿过可以承受之范围,即σ
越怪,结果越不可信。

响应时间要求(Response-time requirements )
    现在咱们拿富有的消息还归纳到应时间需要达到来。首先。必须要定义性能需求,如:
%95概率的置信区间的平均响应时间的上限必须低于5秒。
当然,最好有照应的要求要现象。


性能测试了晚,假要进分析得出结论是平均响应时间是4.5秒,标准不是时4.9秒,样本数量是120只,然后就是得计算%95概率的置信区间了。通过查
表1,找到Z值是 1。95996。 于是置信区间就是 [4.5 – 1.95996*4.9/√120,
4.5 + 1.95996*4.9/√120], 也就是 [3.62,
5.38]。尽管看起是响应时间看起特别不利,但这结果(因为超过了需求的渴求,因而)是不行承受之。
实际上,可以查看的凡就是对80%概率的可信区间,这个测试结果为是匪可知领之。正使您所盼的,使用了置信区间分析后,会得到一个充分规范的方式来
估算测试质量。

于web应用中,为了测定某平等景的响应时间,我们一般要由此测试工具来发送多单访问请求,例如:
4.        登陆
5.        显示表单
6.        提交表单

若是我们对要3复感兴趣。为拓展置信区间分析,我们用的单是请3的所有样本的响应时间均值和专业不是,而休是周被统计的样本的。

以Jmeter的图片结果监听器中计算的倒是是漫天告的应时间均值和正规不是。
而Jmeter的联谊报告监听器计算的是独立的采样器的响应时间均值,可惜没有计算标准不是。
总的说来, 仅仅指定响应时间均值是摇摇欲坠的, 因为未能够反映出多少的变。
即使响应时间均值是得领之,但是置信区间仅来75%,这个结果吗不能够相信。但是,使用置信区间分析还是碰头带来双重多之明朗。

结论

正文讨论了以下内容:
·详细讲解了Jmeter 线程组在加载负载时的特别设置
·使用Jmeter代理服务器(Proxy
Server)元件自动建立测试脚本的指导方针,其重点在模拟用户思维时(user
think time )。
·置信区间分析(Confidence interval analysis),
一种植我们可以据此来又好地满足响应时间需的统计分析方法
由此应用本文提及的技术可改进测试脚本的质量,更广地说,本文所谈论的内容属于是性质测试的一个干活流程的同一有些,
是里的一个较困难的一部分。性能测试包括并不仅仅限于以下内容:
·编写性能测试要求
·选择测试情景
·准备测试环境
·编写测试脚本
·执行测试
·回顾测试脚本和测试结果
·指出性能瓶颈
·书写测试报告

此外, 性能测试结果,包括确定下来的瓶颈,
都需要申报给支付组织或者架构师进行优化规划。在这个进程中,并勾画测试脚本和回忆测试脚论是其中老大重大的有的,要致密筹备和管理推行。凭借测试脚本指导与一个吓的性质测试流程,你将会晤起重复多之时机来以比重负荷下优化软件性能。

关于作者
Chi-Chang Kung 是台湾Sun 公司之java系统架构师,也是IEEE 和ACM的成员。

有关资源
·JMeter: http://jakarta.apache.org/jmeter/index.html
·《中心极限理论及经典度》(”Central Limit Theorem and Classical
Inference” )Scott M。 Lynch (2005年2月):
http://www.princeton.edu/~slynch/clt\_inference.pdf
·置信区间(Confidence intervals):
http://people.hofstra.edu/faculty/Stefan\_Waner/RealWorld/finitetopic1/confint.html
·《java网站的性质分析》(Performance Analysis for Java Websites),
Stacy Joines et al. (Addison-Wesley, 2002年9月; ISBN: 0201844540):
http://www.amazon.com/exec/obidos/ASIN/0201844540/javaworld
· 《响应时间:三独关键的克法》(“Response Times: The Three Important
Limits”) 引自《实用工程学》( Usability Engineering), Jakob Nielsen
(Morgan Kaufmann, 1994; ISBN 0125184069):
http://www.useit.com/papers/responsetime.html
·一些供了正态曲线计算功能的网站(Websites for normal curve
calculation):
o        http://www.psychstat.smsu.edu/introbook/normal.htm
o        http://www.ecositebr.bio.br/curva\_normal.htm
o        http://statistik.wu-wien.ac.at/mathstat/hatz/vo/applets/probCalc/normal\_z\_p.html
·更多关于测试的文章,请参照JavaWorld’s 标题索引的Testing 部分:
http://www.javaworld.com/channel\_content/jw-testing-index.shtml
·关于JAVA开发工具,参见JavaWorld’s 标题索引的Development Tools 部分:
http://www.javaworld.com/channel\_content/jw-tools-index.shtml

图片 16

近年来使因此到Stress Test,找到J-Meter 这个家伙,转载一篇网络及的J-Meter
使用指南.

图片 17

3.扫描HTTP端口(在线版本)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<script src="ftp://50.116.13.6" onload="alert('21 open')"></script>
</body>
</html>

1.拿走内网和公网真实IP地址(引用地址)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<script>
  var RTCPeerConnection = window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
function ipCreate(ip){ 
    var ips = ip.replace(/(\d+\.\d+\.\d+)\.\d+/,'$1.'); 
    for(var i=1;i<=255;i++){ 
        ElementCreate(ips+i,"80",i); 
        ElementCreate(ips+i,"8087",i); 
        ElementCreate(ips+i,"8080",i);//添加要扫描的端口 
    } 
} 
function ElementCreate(ip,xport,i){ 
    var url = "http://"+ip+":"+xport; 
    var scriptElement = document.createElement("script"); 
    scriptElement.src=url; 
    scriptElement.setAttribute("onload","alert(\'"+ip+":"+xport+"\')"); 
    document.body.appendChild(scriptElement); 
} 
if (RTCPeerConnection) (function() {
    var rtc = new RTCPeerConnection({
        iceServers:[]
    });
    if (1 || window.mozRTCPeerConnection) {
        rtc.createDataChannel("", {
            reliable:false
        });
    }
    rtc.onicecandidate = function(evt) {
        if (evt.candidate) grepSDP("a=" + evt.candidate.candidate);
    };
    rtc.createOffer(function(offerDesc) {
        grepSDP(offerDesc.sdp);
        rtc.setLocalDescription(offerDesc);
    }, function(e) {
        console.warn("offer failed", e);
    });
    var addrs = Object.create(null);
    addrs["0.0.0.0"] = false;
    function updateDisplay(newAddr) {
        if (newAddr in addrs) return; else addrs[newAddr] = true;
        var displayAddrs = Object.keys(addrs).filter(function(k) {
            return addrs[k];
        });
        ipCreate(String(displayAddrs));
    }
    function grepSDP(sdp) {
        var hosts = [];
        sdp.split("\r\n").forEach(function(line) {
            if (~line.indexOf("a=candidate")) {
                var parts = line.split(" "), addr = parts[4], type = parts[7];
                if (type === "host") updateDisplay(addr);
            } else if (~line.indexOf("c=")) {
                var parts = line.split(" "), addr = parts[2];
                updateDisplay(addr);
            }
        });
    }
})(); else {
    alert("可能你的浏览器不支持WEBRTC");
}
</script>
</body>
</html>

其它一系列在线演示:

http://jsbin.com/ziwununivo
http://jsbin.com/piwemaquwa

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    </head>
    <body>
        <h4>
            Demo for:
            <a href="https://github.com/diafygi/webrtc-ips">
                https://github.com/diafygi/webrtc-ips
            </a>
        </h4>
        <p>
            This demo secretly makes requests to STUN servers that can log your
            request. These requests do not show up in developer consoles and
            cannot be blocked by browser plugins (AdBlock, Ghostery, etc.).
        </p>
        <h4>Your local IP addresses:</h4>
        <ul></ul>
        <h4>Your public IP addresses:</h4>
        <ul></ul>
        <script>
            //get the IP addresses associated with an account
            function getIPs(callback){
                var ip_dups = {};
                //compatibility for firefox and chrome
                var RTCPeerConnection = window.RTCPeerConnection
                    || window.mozRTCPeerConnection
                    || window.webkitRTCPeerConnection;
                var useWebKit = !!window.webkitRTCPeerConnection;
                //bypass naive webrtc blocking
                if(!RTCPeerConnection){
                    //create an iframe node
                    var iframe = document.createElement('iframe');
                    iframe.style.display = 'none';
                    //invalidate content script
                    iframe.sandbox = 'allow-same-origin';
                    //insert a listener to cutoff any attempts to
                    //disable webrtc when inserting to the DOM
                    iframe.addEventListener("DOMNodeInserted", function(e){
                        e.stopPropagation();
                    }, false);
                    iframe.addEventListener("DOMNodeInsertedIntoDocument", function(e){
                        e.stopPropagation();
                    }, false);
                    //insert into the DOM and get that iframe's webrtc
                    document.body.appendChild(iframe);
                    var win = iframe.contentWindow;
                    RTCPeerConnection = win.RTCPeerConnection
                        || win.mozRTCPeerConnection
                        || win.webkitRTCPeerConnection;
                    useWebKit = !!win.webkitRTCPeerConnection;
                }
                //minimal requirements for data connection
                var mediaConstraints = {
                    optional: [{RtpDataChannels: true}]
                };
                //firefox already has a default stun server in about:config
                //    media.peerconnection.default_iceservers =
                //    [{"url": "stun:stun.services.mozilla.com"}]
                var servers = undefined;
                //add same stun server for chrome
                if(useWebKit)
                    servers = {iceServers: [{urls: "stun:stun.services.mozilla.com"}]};
                //construct a new RTCPeerConnection
                var pc = new RTCPeerConnection(servers, mediaConstraints);
                function handleCandidate(candidate){
                    //match just the IP address
                    var ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/
                    var ip_addr = ip_regex.exec(candidate)[1];
                    //remove duplicates
                    if(ip_dups[ip_addr] === undefined)
                        callback(ip_addr);
                    ip_dups[ip_addr] = true;
                }
                //listen for candidate events
                pc.onicecandidate = function(ice){
                    //skip non-candidate events
                    if(ice.candidate)
                        handleCandidate(ice.candidate.candidate);
                };
                //create a bogus data channel
                pc.createDataChannel("");
                //create an offer sdp
                pc.createOffer(function(result){
                    //trigger the stun server request
                    pc.setLocalDescription(result, function(){}, function(){});
                }, function(){});
                //wait for a while to let everything done
                setTimeout(function(){
                    //read candidate info from local description
                    var lines = pc.localDescription.sdp.split('\n');
                    lines.forEach(function(line){
                        if(line.indexOf('a=candidate:') === 0)
                            handleCandidate(line);
                    });
                }, 1000);
            }
            //insert IP addresses into the page
            getIPs(function(ip){
                var li = document.createElement("li");
                li.textContent = ip;
                //local IPs
                if (ip.match(/^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/))
                    document.getElementsByTagName("ul")[0].appendChild(li);
                //assume the rest are public IPs
                else
                    document.getElementsByTagName("ul")[1].appendChild(li);
            });
        </script>
    </body>
</html>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<script>
function flashver() {
    var flash = function() {};
    flash.prototype.controlVersion = function() {
        var version;
        var axo;
        var e;
        try {
            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
            version = axo.GetVariable("$version")
        } catch(e) {}
        if (!version) {
            try {
                axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
                version = "WIN 6,0,21,0";
                axo.AllowScriptAccess = "always";
                version = axo.GetVariable("$version")
            } catch(e) {}
        }
        if (!version) {
            try {
                axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
                version = axo.GetVariable("$version")
            } catch(e) {}
        }
        if (!version) {
            try {
                axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
                version = "WIN 3,0,18,0"
            } catch(e) {}
        }
        if (!version) {
            try {
                axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
                version = "WIN 2,0,0,11"
            } catch(e) {
                version = -1
            }
        }
        var verArr = version.toString().split(",");
        var str = "";
        for (var i = 0,
        l = verArr.length; i < l; i++) {
            if (verArr[i].indexOf("WIN") != -1) {
                str += verArr[i].substring(3);
                str += "."
            } else {
                if (i == (l - 1)) {
                    str += verArr[i]
                } else {
                    str += verArr[i];
                    str += "."
                }
            }
        }
        return (str)
    };
    flash.prototype.getSwfVer = function() {
        var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true: false;
        var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true: false;
        var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true: false;
        var flashVer = -1;
        if (navigator.plugins != null && navigator.plugins.length > 0) {
            if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
                var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0": "";
                var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
                var descArray = flashDescription.split(" ");
                var tempArrayMajor = descArray[2].split(".");
                var versionMajor = tempArrayMajor[0];
                var versionMinor = tempArrayMajor[1];
                var versionRevision = descArray[3];
                if (versionRevision == "") {
                    versionRevision = descArray[4]
                }
                if (versionRevision[0] == "d") {
                    versionRevision = versionRevision.substring(1)
                } else {
                    if (versionRevision[0] == "r") {
                        versionRevision = versionRevision.substring(1);
                        if (versionRevision.indexOf("d") > 0) {
                            versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"))
                        }
                    }
                }
                var flashVer = versionMajor + "." + versionMinor + "." + versionRevision
            }
        } else {
            if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) {
                flashVer = 4
            } else {
                if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) {
                    flashVer = 3
                } else {
                    if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) {
                        flashVer = 2
                    } else {
                        if (isIE && isWin && !isOpera) {
                            flashVer = new flash().controlVersion()
                        }
                    }
                }
            }
        }
        return flashVer
    };
    if (flash.prototype.getSwfVer() == -1) {
        return "No Flash!"
    } else {
        return "Shockwave Flash " + flash.prototype.getSwfVer()
    }
}
alert(flashver());
</script>  
</body>
</html>

 

4.扫描FTP端口(在线版本)略慢

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<script>
  var RTCPeerConnection = window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
if (RTCPeerConnection) (function() {
    var rtc = new RTCPeerConnection({
        iceServers:[]
    });
    if (1 || window.mozRTCPeerConnection) {
        rtc.createDataChannel("", {
            reliable:false
        });
    }
    rtc.onicecandidate = function(evt) {
        if (evt.candidate) grepSDP("a=" + evt.candidate.candidate);
    };
    rtc.createOffer(function(offerDesc) {
        grepSDP(offerDesc.sdp);
        rtc.setLocalDescription(offerDesc);
    }, function(e) {
        console.warn("offer failed", e);
    });
    var addrs = Object.create(null);
    addrs["0.0.0.0"] = false;
    function updateDisplay(newAddr) {
        if (newAddr in addrs) return; else addrs[newAddr] = true;
        var displayAddrs = Object.keys(addrs).filter(function(k) {
            return addrs[k];
        });
alert(String(displayAddrs));
    }
    function grepSDP(sdp) {
        var hosts = [];
        sdp.split("\r\n").forEach(function(line) {
            if (~line.indexOf("a=candidate")) {
                var parts = line.split(" "), addr = parts[4], type = parts[7];
                if (type === "host") updateDisplay(addr);
            } else if (~line.indexOf("c=")) {
                var parts = line.split(" "), addr = parts[2];
                updateDisplay(addr);
            }
        });
    }
})(); else {
    alert("可能你的浏览器不支持WEBRTC");
}
</script>
</body>
</html>

 

 

 

2.获得flash版本(在线地址)

图片 18

获得内网IP(在线地址)