性能测试工具 关于 jmeter 性能测试的 局限性

wonder1z · 2018年03月21日 · 最后由 heulizeyang 回复于 2018年10月09日 · 15898 次阅读
本帖已被设为精华帖!

这两天做压测,用了Constant Throughput Timer 来限制QPS。

被压测接口最大TPS 为110左右,在QPS达到110前,QPS = TPS,而 QPS>110后,接口TPS会稳定在110。如下图
再增加线程和Timer配置都只会导致响应时间的增加,TPS 却不会增加,并且无报错(注:QPS指每秒请求数,TPS指每秒处理请求)

我就在想,如果接口 收到的QPS 远大于他的处理能力,理论上应该会报错,并且处理能力(TPS)下降, 那为什么 TPS会稳定呢。
我分析了下测试数据(下图),

以 10线程 40QPS 和 75线程 300QPS为例,
10线程时的平均响应时间 为0.113s,他可以造成10/0.113=88 的QPS,但因为Throughput Timer 配置了2400(也就是40QPS),所以他实际QPS为40
75线程时平均响应时间为0.625,对应QPS 为75/0.625=120,而我设置的Throughput Timer是18000(300QPS),所以75线程时,jmeter根本就没法提供300QPS
500线程结果和75线程 差不多,虽然 线程和 QPS配置上去了,但因为响应时间 增加,实际的QPS 只能达到120左右。
所以我最终得出结论是,jmeter 能提供的最大QPS 只能为接口TPS , 也就是说,jmeter不能提供更高的QPS 来压爆接口

另外,我用apache的AB 也做了同样的测试,结论是一样的。

对于这个结论 我也很吃惊,不知道有没有漏洞,欢迎各位拍脸

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 84 条回复 时间 点赞
1楼 已删除

那其实还是说明,jmeter能提供的 QPS有限嘛

也就是说,jmeter不能在 服务器只能处理100个请求每秒的情况下,提供200QPS的 压力

4楼 已删除

jmeter这个锅不背

zailushang 回复

他凭什么不背😑 ,我设置的 QPS 他根本达不到

zailushang 回复

我猜你压测的对象 能达到 2W 的TPS,如果2W 是他的上限,你就不可能再提高QPS了

wonder1z 回复

从这里来看,你是想测试业务的性能拐点吗?
如果你想测试性能拐点,首先要保证你的压测服务器本身不是瓶颈,确保真的发出了你所设置的线程或者并发

哥,从你回答的jmeter和loadrunner这两个问题来看,你是不是离开一线时间太长了???

zailushang 回复

对,是想测拐点, 4核E5 16G 的压测服务器 没有什么压力。我的结论是QPS瓶颈是jmeter自己的,他因为要等待 线程返回 再进行下一次请求,所以你线程设置的再高没用,只有第一次请求能达到 那么多并发。 时间长 了 QPS 就达不到了

12楼 已删除
wonder1z 回复

你碰到的这个问题,具体分析,如果是你服务器端的连接数有限,导致的QPS上不去,你就是再多的并发用户,也进不去真正的队列
当你的连接数够大的时候,你的并发用户才能真正的进行排队,然后对你的服务器才有真实的压力

让我想起来最近面试,碰到的一个研发部门总监,问我loadrunner的参数化怎么做的,我还心想问这个干什么,这不是很基本的问题嘛
后来才知道,他的使用经验在2000年的时候。

公司面试流程还是很重要的,如果脱离太久,就不要问那种问题了

15楼 已删除

从题主的答案和推理逻辑,以及你的“这个服气” 里面看出来的,并没有了解到问题的本质,不了了之的“服气”

17楼 已删除
zailushang 回复

我压测对象是 生产环境的 阿里云服务器(施压服也是阿里云内网),有没有连接数限制 我不清楚,但是 远不至于最大只支持100 个同时连接

我要找的吞吐量拐点 是 下降的拐点, 上升的拐点 不就是图中的 110 吗

wonder1z 回复

你是外网压测的,还是内网压测的?

zailushang 回复

内网, 从 阿里云A 压 阿里云B

wonder1z 回复

100个同时连接??听着很耳熟喔,会不会是电信运营商或者操作系统本身的限制?

补充一点吧,这个接口TPS只有100是因为他调用了第三方的接口, 纯前端 接口 TPS能达到 500~600

wonder1z 回复

分两方面去验证这个问题吧:
1、验证你的业务性能,可以用多台jmeter或者其他测试工具去做;
2、验证jmeter的压力性能,可以在验证了你的服务能力后,用不同的压力工具去做同类对比,然后再得出结论

阿里云不会帮你优化设置服务的连接数,还是需要你们开发运维去配置的,tomcat之类的默认线程池连接数都不大,要想提高服务器并发处理能力,连接数是首先要调整的,否则限制住了,你客户端请求再多也上不去,池子就这么大;

biyunfei 回复

你们好像搞错重点了😂 ,帖子的标题才是我发这个帖子的目的,我要说的是jmeter 的问题,他提供的QPS受限于服务器处理能力,导致 我不能 给100tps的接口 施加200qps的压力。也就找不到 服务器最大能承受 QPS,即 什么时候开始 服务崩溃,连接超时等。

那你需要定制了,现在的压测机制下并发用户请求都是要等待返回后再继续请求,而不是单方面的狂轰滥炸了;自己写一个工具搞吧

biyunfei 回复

所言极是

30楼 已删除

我假设 服务器每秒能处理 10000并发,并且在10000并发下 服务一切正常,这个时候你用jmeter 配置20000线程,去压测,我的观点是,jmeter只能造成1W QPS, 因而 服务 不会挂。 你配置的线程数 并不是实际造成的并发。不然 按我上面的数据,500线程 压100tps的接口为什么 一个报错都没有

32楼 已删除

就我觉得。。。。。。。。。。要多看看响应时间,把请求的响应时间打点出来 ,然后根据线程数跟请求书自己再去重新算一遍tps,争论这些意义不大。

34楼 已删除

如果你的服务器性能只能处理110QPS的请求,那么即使JMeter在第一秒发起了200个请求,服务器只能处理110个,剩下的90个会在Web服务器的处理队列里面,连接会被挂起,JMeter也会一直等待这些请求响应,所以QPS才会稳定在110。
而且现在的Web服务器这方面都处理得很好,基本不会出现因为并发量高使服务器宕机的情况。
除非请求量特别大特别大,比如双11那种量级的。。。

arrow 回复

是这个意思

wonder1z 回复

你可以设置一下tomcat的maxProcessors-最大处理线程acceptCount-最大连接数,比如都设置成1000。
还有,测试的时候监控一下服务器的CPU、内存、IO,看看瓶颈在哪里。
具体情况还要根据你们的业务类型来具体分析。

38楼 已删除

1.QPS指每秒查询数,通常用来记DB的性能的。 还是第1次看到QPS=RPS的说法。我猜,jmeter QPS这个指标应该还是指db sql代码的性能测试吧。jmeter不熟,只能猜了。

2.主流性能测试工具都是需要等回应的,如果事务返回正确,只有1个接口,一般RPS=TPS,经常用LR的一般会看到这结果。

3.RPS!=TPS,猜测一般是客户端发送没有出去,或者看看你单机处理的客户端流量,客户端也是需要做下监控的。

4.从结果来看,如果压测机的流量正常,服务端的处理能力已经达到最大了。如果资源很少,你查一下一些参数设置,有可能是他们的影响。

5.第4点排除后,如果你想让他报错,就继续加vuser吧,500一个请求也才4s,默认超时是60s。有时虽然没有报错,但不一定代码时间上可以接受。

6.如果你想,压力机vuser N多,不等回应,然后分开计算RPS和TPS。 你可以尝试用python Gevent + scrapy,可以实现发和回的异步事件操作。

qwen 回复
  1. 在服务器能够处理的过来的时候(也就是RPS小于接口最大TPS),RPS=TPS。
  2. 我的数据应该说明的很清楚了,jmeter再增加线程 也不能造成更高的 RPS,所以jmeter测试不了 RPS>TPS的情况
  3. 我帖子的主要目的是说明jmeter的这个问题,不是为了说怎样测试服务器性能
  4. 我自己写了个python多线程的脚本,只发请求,不管请求响应。很快 第三方接口(我压测的接口瓶颈在第三方)就出现了超时的异常。只不过这个脚本不太好做数据统计。代码如下:
# -*- coding:utf-8 -*-
import threading,time,requests

def post():
url = 'http://***/'
param = {'message':'***','client_acc_code':'***'}
start = time.time()
res = requests.post(url,param)
if res.status_code!=200:
print(threading.current_thread().getName() + ' error : ' + str(res.status_code))
else:
end = time.time()
print(threading.current_thread().getName() + ' : ' + str(end - start))

if __name__=='__main__':
run_time = 60 #执行次数
thread_count = 100 #并发数
for x in range(run_time):
i = 0
while i < thread_count:
i += 1
t = threading.Thread(target=post)
t.start()

同步堵塞,接口响应慢,肯定上不去啊,再怎么者也不会出现jmeter就能跑几百

jmeter的请求方式是同步线程请求,基于这种请求方式,首先线程数不等于并发量,qps也只取决于服务器的处理速度。
如果想要产生更高的压力的话,应该用异步线程,每秒发起多少次请求,然后就不管了,等下一秒再发起多少请求,这种才是真正的并发。

m58944869 回复

这就是我这个帖子要表达的,很多人并不了解,包括我之前也误以为 jmeter可以制造无限大的压力。

keithmork 回复

你这 大概就是100分的答案吧😑

46楼 已删除

看大佬们的讨论长知识

48楼 已删除
Lihuazhang 将本帖设为了精华贴 03月26日 17:21

全部看完了,,,这个还是jmeter性能测试的局限性吗?怎么看都不像是jmeter的性能测试局限性吧,自己写的工具不也是受限于作为压测机本身的资源限制?服务器的设置限制吗?为何就似乎成了jmeter独家赞助的样子了。。。期待新的答疑:)

onionyao 回复

单实例jmeter不能造成大于服务器处理能力的压力,这就是他的局限性

解释下加精理由,讨论区比较精彩,可以学到不少性能测试的东西。

如果用jmeter自定义java请求,忽略返回结果,是否可以达到QPS持续增加的条件

概念错误

我也遇到同样的问题,jmeter端的QPS在100线程时只有50,希望能发送200请求/s到服务端,到底应该怎么实现呢?

nsirone 回复

希望解释下所说的概念错误,这么简短你的回答不利于交流学习呀。

这不能算是局限性,只是对于jmeter在请求配置上的限制问题,当设置所有的请求均为1s超时时,可以类比实现tps=线程数的效果,jmeter默认使用httpclient4,可以在HTTPHC4Impl的setupRequest()方法中增加超时时间限制

   protected void setupRequest(URL url, HttpRequestBase httpRequest, HTTPSampleResult res)
throws IOException {

HttpParams requestParams = httpRequest.getParams();
...
log.info("add timeout :100ms");
requestParams.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 1000);
requestParams.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1000);//设置请求均为1000ms超时

/* 下面是jmeter原本的实现,请求超时时间应该是可配置的
int rto = getResponseTimeout();
if (rto > 0){
requestParams.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, rto);
}

int cto = getConnectTimeout();
if (cto > 0){
requestParams.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, cto);
}*/

学了不少知识

Jmeter和LR都是一样的机制,同步等待返回。所以如果服务器只能有200TPS,你加再多线程,都是一样的结果。
如果你想要达到超过200的效果,你可以设置超时时间,也就是将发送请求之后等待响应这段等待时间缩短,到达超时时间就会报错,放弃等待而发送下一个请求。

我觉得还是要结果导向的,比如楼主所说的Jmeter局限性,其实不是重点,44楼的大神说的比较清楚了,所以现在好奇的知识点是:
1.限制QPS的作用是啥?
2.QPS和TPS的对比有什么实际作用?拐点能代表什么东东?
不知道有没有大神解惑~
@fudax @keithmork

推荐一个go写的工具https://github.com/tsenart/vegeta,感觉这个工具可以满足楼主需求

62楼 已删除

概念都没理清楚....如果只是想做断链攻击的话 可以缩小响应时间

如果题主说的QPS是每秒请求数,TPS是每秒交互数。

那就先说下我的看法:如果想得到有效的测试结果,那压力机的QPS是不可以大于服务器极限TPS的。

举个例子,假如QPS比TPS大100,那压力机每秒都会多出100个在等待状态的连接对不对?。时间一久,会有多少在等待的连接?先不说服务器,压力机自己就要炸了。
so,这样的压力机只能提供不可控也不稳定的压力,如楼上所问,这样的压测结果意义何在呢?

能提供稳定压力的压力机在不做特殊配置和丢包的情况下,每个线程都是在等待服务器响应结果后才会发下一个请求,这就意味着压力机的QPS就是要等于服务器的TPS的。

一些评论中的说法,我觉得还是有误导性的。 希望大家可以辩证的看。

wonder1z 回复

threading 改为 concurrent.futures 会好很多

涨姿势了~感谢大神耐心回复~😊
还是有点疑惑,好像每个人对TPS的理解都不太一样,难道是术语没有在业界统一么😅 ,记得以前拿LR做性能的时候TPS就是每秒事务数,是根据在脚本里添加事务来确定某几个请求算一个事务的(一般来说是一个请求一个事务,此时可以理解QPS=TPS),但是不知道TPS和吞吐量有什么关系,好像用TPS的曲线来找拐点和吞吐量是一个意思吧?
另外还是不清楚限流的实际应用场景有哪些,莫非防止服务器报警ddos攻击?😂

67楼 已删除
68楼 已删除
69楼 已删除

你这是知道了服务器 是120的TPS, 那你不知道的时候呢,如果服务器的TPS是1000,我限制300有问题吗。 并且 我贴子不就是说明120TPS的时候jmeter达不到300RPS吗? 这不就是jmeter作为BIO 的局限性吗。 我想寻找下降拐点 来判断 服务器最大能承受的RPS,有问题吗, 120是 服务器能承受的最大RPS吗?

wonder1z 回复

首先你压测出120是就是服务器能承受的最大RPS,再多哪怕一点点,持续下去拐点都会出现,但要等多久就说不好了。(为什么,请看吓我楼上的回复)
你可以用AIO或者NIO的方式模拟用120+的rps去试试,但是用异步请求的客户端,自身的稳定性和压测数据的统计实现起来都是个问题。就算出现拐点了客户端也不知道。

这里jmeter作为BIO不存在这些问题,通过实时增加并发数就可以测出最大TPS和拐点,这也是为什么主流的压测机都是BIO的原因

44楼大神已经说过了rps>tps可以通过 jmeter多实例和分布式来实现,我自己也有测过, 完全不会出现你所推测的压力机自爆压力不稳定的情况。你那么笃定的说 120就是 服务器能承受的最大rps我认为也是没有依据的。后续我自会进行详细的测试

wonder1z 回复

1.44楼哪句说了jmeter多实例和分布式可以做到rps>tps?
2.RPS>TPS压力机没炸只有三种可能:要么你测试脚本没做到RPS大于TPS,要么压测时间还不够长,要么服务器先炸了。
3.一般情况下, jmeter增加线程数测的TPS不变的时候,对应的tps就是服务器能承受的最大rps,也就是120。
另外,欢迎找个公网接口贴测试结果来反驳我的结论


多的我不想解释了也不想反驳了,我自己测过我自然知道。

wonder1z 回复

我晕,他说的更高的压力明明指的是线程数(并发数)! 这也能被理解成QPS……

我也不期待能说服你什么了,大家各忙各的吧。

pignay 回复

兄弟,别人知道jmeter是BIO,会认为更高的线程能造成更高的压力吗。另外 线程!=并发。

wonder1z 回复

1.不需要知道什么是BIO,看过官方文档的就会认为更高的线程能造成更高的压力 (Number of Threads:Number of users to simulate.)
2.我根本没说线程==并发,这是你的误解。只是线程数和并发量一般都成正比,同样可以量化压力,方便你更好理解我才写括号里的。

再抬杠下次我可要收学费了哦。

pignay 回复

请你再把我主贴看一遍 高线程等不等于高压力

wonder1z 回复

高线程等不等于高压力?44楼的回帖你真的看懂了么?
增加线程没有增加压力的话,那服务器响应的延时会增加是因为什么呢?

pignay 回复

没看懂的是你啊 老弟,线程的等待时间也算进 响应时间了

wonder1z 回复

那线程在等什么呢? 等迟钝了的服务器的返回对不对? 压力没增加那为什么服务器迟钝了?

pignay 回复

算了,你自己琢磨吧

wonder1z 回复

没办法,实在琢磨不出来,为啥我的反问句会被理解成疑问句

只要是同步返回的接口,并且要统计响应时间的,任何工具都达不到“提供更高的QPS 来压爆接口”吧;不仅仅是jmeter。要达到压爆的效果,就和楼主写个死循环,只管发,不管返回呗

哦,你说单实例那确实,不过人家也提供了分布式多台压测解决方案了:) 另外如果服务器比较刚后台程序的实现架构也比较合理(比如线程池,连接池,异步处理mq的引入等),就算自己写工具,作为单例的压测端来说,也很难压倒服务器,基本也都是要考虑多机分布式压测了吧。

你把概念混乱了, 这就是个典型的接口压力测试. 你举例说明的那个75线程计算结果是实际的TPS, jemter发起的并发请求就是300,只是服务接口压力瓶颈在110左右,他把所有请求放在队列(猜测的)中处理,只要你的断言不设置超时就不会抛出异常.不是jemter上限只能发起110左右的request. 不谈响应时间的并发量是耍流氓

一点拙见:
这里有 线程数 TPS 响应时间 QPS 四个概念,
以例子中10个线程的数据来说,jemeter使用10个线程向业务发送请求,业务方平均处理平均响应时间为113毫秒,那么在第一个113毫秒(虽然是平均响应时间,这个地方简化理解,我当每个请求的处理都是113毫秒了)jemeter 10个线程收到第一轮结果后立马再向业务方发送请求。。。 如此 在1秒之内 jemeter的10个线程可以发送的请求数大概为88个,由于楼主固定了QPS,告诉jemeter你一秒内发40个就可以了,所以TPS只有40个。

jemeter是利用线程循环使用来发送请求的,基于这点的话 QPS <= TPS。

楼主期望jemeter 提供高于业务方处理能力的请求数,应该不限制QPS,而是提高线程数。
比如业务服务现在每秒只能处理100个请求,jemeter使用100个线程进行压测,平均响应时间应该就是1秒,现在楼主想压爆业务接口制造每秒200个请求,直接设置200个线程,结果就是有100个线程的请求能处理,另外100个请求业务方可能就是等待了,从结果看平均响应时间就会降低。
想压爆接口 其实目的是为了看接口能处理多大的请求,而不是已经知道处理的请求数再去做压测,有点本末倒置了。
这时候要看业务服务端能不能满足需求,不满足就要提高处理能力或者新增机器了。

这么简单的一个问题,居然还精华,居然还有这么多人讨论,吃惊

在测试压力的时候应该注意响应时间和成功率

biyunfei 回复

可以使用gatling压测工具 请求是同时发出的

qps 和tps 有什么对比性吗, 参见上面一位仁兄的答案, 我理解的qps一般适用于 db 和 磁盘的性能,对于一般应用, 得出qps 和tps 有什么可参考性吗

看评论就像看网易的帖子一样,真不错!

看不下去了,如果题主参加工作不久,发这帖子也能理解;如果已经多年,或者冠上高级的title了,只能呵呵了。这个问题还能在这论坛讨论这么久,还能吵起来,说明啥,说明这论坛、论坛会员都还处于初级阶段。遇到这类帖子,管理员应该直接移到新手技术区,竟还放在首页这么久。。。

还好后面有几个明白人啊

单实例jmeter不能造成大于服务器处理能力的压力,这就是他的局限性, 这句貌似不太准确吧。 我觉得方法可以是:

  • 可以不限制固定QPS
  • 增加线程数,甚至可以设定集合时间点,假设服务器极限TPS到100,你JMETER 线程数200个,同时设置集合点200个线程同时发

这样同时发,不就是超过你服务器极限TPS了吗,但是服务器TPS就这么多呀,TPS就是这么多了,但是客户端的响应时间肯定很难看。 服务器不一定会挂(说明服务器的保护不错呀),有很多等待的队列,客户端反应就是超时越来越多,错误比例越来越高。

同样如果有监控系统看的,可以从服务端的角度看系统处理时间,在这种情况下,客户端响应时间和服务端的监控的响应时间数据我觉得会有不一样

一般测试测接口不都去测接口的极限TPS,也就是拐点么?值都测出来了就可以了啊,再去增加所谓的QPS/RPS,如果服务端优化的够好,多余的请求都会进队列(NSQ)一类的东西进行排队,保证服务器不挂,代价就是响应时间越来越长而已,但是接口的处理能力就在那里了,一秒110个,你再怎么加,也只能还是110/s的处理能力,对于压力机来讲,最多也就1s能收到110个返回

wonder1z 回复

如果服务器只能处理100个,那么jmeter给了200,但是tps也上不去,但是起码你知道了服务器最大处理事务的能力是多大。那么这个时候不管jmeter有没有局限性,就算他不受你说的这个局限性限制,那么你给再多的并发量,最终发现的问题都是服务器最大支持的处理能力是多少。

什么是QPS,什么是TPS,楼主你真的清楚吗???

我想问下,TPS有100, jmeter配置了300个并发线程数,那多的线程数是在jmeter这边排队等待发送,还是在压测服务器端排队。

系统资源有限,运行在这个系统上面的资源必然都是有限的,8G的内存难不成你能消耗掉9G?
性能问题,先分析请求链路的最下游,逐渐往上推。服务器那边统计的响应时间都没有,怎么得出的结论?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册