一次性能测试中,涉及到好多指标,比如TPS、RPS、QPS、HPS、CPM等
建议使用TPS作为关键的性能指标。另外,TPS中的T(事务/请求)要根据实际的业务产生变化
TPS和并发数是什么关系?在并发中谁来承载“并发”这个概念呢?
首先需要区分一下“绝对并发”和“相对并发”这两个概念
- 绝对并发指的是同一时刻的并发数
- 相对并发指的是一个时间段内发生的事情
什么是并发
下面我们就来说一下“并发”这个概念
我们假设上图中的这些小人是严格按照这个逻辑到达系统的,那显然,系统的绝对并发用户数是 4。如果描述 1 秒内的并发用户数,那就是 16。
但是,在实际的系统中,用户通常是这样分配的:
也就是说,这些用户会分布在不同的服务、网络等对象中。这时候“绝对并发”这个概念就难以描述了,你说的是哪部分的绝对并发呢?
要说积分服务,那是 2;要说库存服务,那是 5;要说订单服务,它自己是 5 个请求正在处理,但同时它又 hold 住了 5 个到库存服务的链接,因为要等着它返回之后,再返回给前端。所以将绝对并发细分下去之后,你会发现头都大了,不知道要描述什么了。
有人说,我们可以通过CPU啊,IO啊,或者内存来描述绝对并发,来看CPU在同一时刻处理的任务数。如果是这样的话,绝对并发还用算吗?那肯定是CPU的个数呀。有人说,CPU 1ns 就可以处理好多个任务了,这里的 1ns 也是时间段呀。要说绝对的某个时刻,任务数肯定不会大于 CPU 物理个数。
所以,“绝对并发”这个概念,不管是用来描述硬件细化的层面,还是用来描述业务逻辑的层面,都是没有什么意义的。
我们只要描述并发就好了,不用有“相对”和“绝对”的概念,这样可以简化沟通,也不会出错。
那如何来描述上面的并发用户数呢?建议用TPS来承载并发这个概念。
并发数是16TPS,也就是1s内整个系统处理了16个事务。
在线用户数、并发用户数计算方式
在线用户数和并发用户数有应该如何计算?下面我们接着来看示意图:
如上图所示,总共有32个用户进入了系统,但是绿色的用户并没有什么动作,那么显然,在线用户是是32个,并发用户数是16个,这时的并发数就是50%。
但是在一个系统中,通常实际上都是下面这个样子的:
- 为了能hold住更多的用户,我们通常都会把一些数据放到redis这样的缓存服务器中。所以在线用户数什么算呢?如果仅从上面这种简单图来看,其实就是缓存服务器能够有多大,能hold住多少用户需要的数据。最多再加上超时路上的用户数(问题:超时路上的用户数是什么)
- 假设一个用户进入系统之后,需要用10K内存来维护一个用户的信息,那么 10G 的内存就能 hold 住 1,048,576 个用户的数据,这就是最大在线用户数了。在实际的项目中,我们还会将超时放在一起来考虑。
- 但是并发用户数不同,他们需要在系统中执行某个动作。我们要测试的重中之重,就是统计这些正在执行动作的并发用户数。
- 当我们统计生产环境中的在线用户数时,并发用户数也是要同时统计的。这里会涉及到一个概念:并发度
要想计算并发用户和在线用户之间的关系,都需要有并发度。
做性能的人都知道,我们有时会接到一个需求,那就是一定要测试出来系统最大在线用户数是多少。这个需求怎么做呢?
在此之前,我们需要先理解压力工具中的线程或用户数到底是不是用来描述性能表现的?我们通过一个示意图来说明:
通过这个图,我们可以看到一个简单的计算逻辑:
- 如果有 10000 个在线用户数,同时并发度是 1%,那显然并发用户数就是 100。
- 如果每个线程的 20TPS(每秒能够处理20个事务),显然只需要 5 个线程就够了(5*20TPS = 100,5个线程就能应对100个并发用户数的请求)(请注意,这里说的线程指的是压力机的线程数)。
- 这时对 Server 来说,它处理的就是 100TPS(5*20TPS=100TPS),平均响应时间是 50ms。50ms 就是根据1000ms/20TPS 得来的(请注意,这里说的平均响应时间会在一个区间内浮动,但只要TPS 不变,这个平均响应时间就不会变)。
- 如果我们有两个 Server 线程来处理,那么一个线程就是 50TPS,这个很直接吧。
- 请大家注意,这里有一个转换的细节,那就是并发用户数到压力机的并发线程数。这一步,我们通常怎么做呢?就是基准测试的第一步。关于这一点,我们在后续的场景中交待。
而我们通常说的并发这个词,依赖TPS来承载的时候,指的都是server端的处理能力,并不是压力工具上的并发线程数。在上面的例子中,我们说的并发就是指服务器上100TPS的处理能力。
实例
我们可以看到,JMeter的平均响应时间基本都在5ms,因为只有一个压力机线程,所以它的TPS应该接近1000ms/5ms=200TPS。从测试结果上看,也确实是接近的。那为什么会少一点呢?因为这里算的是平均数,并且这个数据是30s刷新一次,用30s的时间内完成的事务数除以30s得到的,但是如果事务还没有完成,就不会计算在内了;同时,如果在这段时间内由一两个时间长的事务,也会拉低TPS。
那么对于服务端呢,我们来看看服务端线程的工作情况。
可以看到在服务端,我开了 5 个线程,但是服务端并没有一直干活,只有一个在干活的,其他的都处于空闲状态。
这是一种很合理的状态。但是你需要注意的是,这种合理的状态并不一定是对的性能状态。
- 并发用户数(TPS)是 193.6TPS。如果并发度为 5%,在线用户数就是193.6/5%=3872
- 响应时间是 5ms
- 压力机并发线程数是 1。这一条,我们通常也不对非专业人士描述,只要性能测试工程师自己知道就可以了
下面我们换一下场景,在压力机上启动 10 个线程。结果如下:
平均响应时间在 25ms,我们来计算一处,(1000ms/25ms)*10=400TPS,而最新刷出来的一条是 396.2,是不是非常合理?
再回来看看服务端的线程:
同样是 5 个线程,现在就忙了很多。
- 并发用户数(TPS)是 396.2TPS。如果并发度为 5%,在线用户数就是396.2/5%=7924
- 响应时间是 25ms
- 压力机并发线程数是 10。这一条,我们通常也不对非专业人士描述,只要性能测试工程师自己知道就可以了
也就是说计算公式为:TPS=响应时间(单位ms)/1000ms∗压力机线程数
也就是说,对于压力工具来说,只要不报错,我们就关心TPS和响应时间就可以了,因为TPS反应出来的是和服务器对应的处理能力,至于压力线程数量是多少,并不关键。也就是说,没有必要在乎Jmeter是BIO还是AIO
那是不是可以这样理解,服务端有多少线程,就可以支持多少个压力机上的并发线程。但这取决于TPS有多少,如果服务端处理得快,那压力机的并发线程就可以更多一点。
这个逻辑看似很合理,但是通常服务端都是由业务逻辑的,既然有业务逻辑,显然不会比压力机块
应该说,服务端需要更多的线程来处理压力机线程发过来的请求。所以我们用几台压力机就可以压十几台服务端的性能了
如果在一个微服务的系统中,因为每个服务都只做一件事情,拆分的很细,我们要注意整个系统的容量水位,而不是看某一个服务的能力,这就是拉平整个系统的容量。
总结
- 通常所说的并发都是指服务端的并发,而不是指压力机上的并发线程数,因为服务端的并发才是服务器的处理能力
- 性能中常说的并发,是用 TPS 这样的概念来承载具体数值的
- 压力工具中的线程数、响应时间和 TPS 之间是有对应关系的
- 常用指标缩写总结: