标签:
对于一个网站,已知服务端的服务线程数和处理单个请求所需的时间时,该如何算出高并发时用户从点击链接到收到响应的时间?注意这个时间并不等于服务端处理单个请求的时间,因为高并发时,很多用户请求需要排队等待,你要把这个额外的等待时间算进去。
这个问题很重要,因为它的结果直接影响你的网站的用户体验。这篇文章就是来帮你算这个时间的。你可以使用本文附带的程序来算,也可以通过本文提炼出的公式来算。
另外还有一个问题:所谓RT(响应时间)和QPS,究竟要不要考虑用户请求的排队等待时间? 本文认为,对于RT我们应该区分出“服务器眼中的RT”和“客户端眼中的RT”,但对于QPS却不必区分。
后文会辨析这些概念,同时还会给出不同场景下,RT和QPS随着并发数变化而变化的曲线图。你可以通过比较不同的曲线,获得一些收获。
下面先推演一个最简单的场景,通过这个场景,你可以了解到本文在计算时使用的基本思路。
如果服务端只有1个服务线程,每处理1个请求需要1个ms; 当客户端在同一瞬间提交两个请求时,各项性能指标是怎样的?
为了解这个题,可以想象一下每个请求被处理的过程:
请求1被立即处理;由于服务线程只有一个,请求2需要等待请求1完结后才能被处理。
据此算出各项性能指标:
性能指标 |
指标值 |
说明 |
服务端响应所有请求的时间 |
1ms + 1ms = 2ms |
上图中紫色时间之和 |
服务端响应每个请求的平均时间 |
服务端处理所有请求的时间/2 = 1ms |
|
客户端所有请求的等待、响应时间 |
1ms + (1ms + 1ms) = 3ms |
第1个请求直接处理 = 1ms 第2个请求先等待后处理 = 1ms + 1ms |
客户端每个请求的平均等待、响应时间 |
客户端所有请求的等待、响应时间/2 = 1.5 ms |
|
看上面高亮的这些字,你应该已经了解了时间推算的基本思路了;后文其他场景中会使用相同的模式来推算。
再来观察一下客户端每个请求的平均等待、响应时间。它的值是1.5ms,大于服务端响应每个请求的平均时间1ms.
不同角度有不同的看法,
这两种说法都有道理。就像银行柜员一直在忙,没有偷懒,问心无愧;而排队的客户苦苦等待,牢骚漫天,其实也很无辜。
因此本文认为,RT应分为两种:
性能指标 |
指标值 |
说明 |
服务端眼中的RT |
1ms |
不计入客户端的等待时间 |
客户端眼中的RT |
1.5ms |
计入客户端的等待时间 |
顺便再算一下此时的QPS. 事实上无论在服务端眼里还是客户端眼里,QPS都是:
成功处理的请求数/(最后一个请求结束时间 – 第一个请求开始时间)= 2 / (2 – 0)ms = 1000
接下来再看看其它场景。
上文说了服务端线程数=1的情况,如果服务端线程数超过1会怎么样? 比如,服务端线程数 = 3, 客户端并发 = 10:
性能指标 |
指标值 |
服务端响应所有请求的时间 |
1ms * 3 + 1ms * 3 + 1ms * 3 + 1ms = 10ms |
服务端响应每个请求的平均时间 |
服务端处理所有请求的时间/10 = 1ms |
客户端所有请求的等待、响应时间 |
1ms * 3 + 2ms * 3 + 3ms * 3 + 4ms = 22ms |
客户端每个请求的平均等待、响应时间 |
客户端所有请求的等待、响应时间/10 = 2.2 ms |
这个推算并不难,但如果总是需要这样手工推算就很烦了。因此,本文提供了一个程序来将推算步骤自动化。不过,在体验这个程序之前,我们先推演一下其他的场景。
以上的场景都假设系统有严格的“过载保护”:只提供有限的服务线程数,由于系统压力不会过载,所以每个线程都总是能以最高的速度来处理请求。
现实中,很多系统并没有这种做,相反:
举个例子,一个应用在并发<=3时,处理单个请求只需1ms;当并发超过3时,处理单个请求的能力开始恶化,
3个并发 => 处理单个请求需1ms
4个并发 => 处理单个请求需要4ms
5个并发 => 处理单个请求需要5ms
…
10个并发 => 处理单个请求需要10ms
如果客户端并发=10,性能会是什么状况?
性能指标 |
指标值 |
服务端响应所有请求的时间 |
10 * 10ms = 100ms |
服务端响应每个请求的平均时间 |
服务端处理所有请求的时间/10 = 10ms |
客户端所有请求的等待、响应时间 |
10 * 10ms = 100ms |
客户端每个请求的平均等待、响应时间 |
客户端所有请求的等待、响应时间/10 = 10 ms |
没有过载保护时,所有请求都不用排队;这时推算性能的算法会比较简单。接下来再看最后一种场景。
有很多应用,在过载保护方面是上面两种机制的折衷:
本文把这种策略称作“弱过载保护”,场景2称作“强过载保护”,场景3则是“无过载保护”。
弱过载保护系统的性能该如何推算?
另外,“强过载保护”和“无过载保护”可以视为“弱过载保护”的特殊情况。
既然所有的场景都可以统一为同一种机制,我们可以搞出一个“统一的性能 - 并发数计算模型”。
输入:
|
符号 |
公式中的符号 |
|
服务器端处理能力 |
第1个线程数阈值 |
serverThreshold1 |
|
第1个线程数阈值前的单个请求处理时间 |
serverResponse1 |
||
第2个线程数阈值 |
serverThreshold2 |
||
两个阈值之间的单个请求处理时间函数 |
serverResponse2Func (clientConcurrency) |
s |
|
客户端压力 |
客户端并发数 |
clientConcurrency |
输出:
|
符号 |
公式中的符号 |
备注 |
|
服务器眼中的性能 |
服务器响应所有请求的时间 |
serverResponseSum |
|
|
服务器响应每个请求的平均时间 |
serverResponseAverage |
serverResponseSum/clientConsurrency |
||
客户端眼中的性能 |
客户端所有请求的等待、响应时间 |
clientWaitResponseSum |
|
|
客户端每个请求的平均等待、响应时间 |
clientWaitResponseAverage |
clientWaitResponseSum/clientConsurrency |
算法:
参照下图,推算出每个请求的处理时间和响应时间,然后分别求和、求平均.
按照上图的模式来手工推演性能会很烦的。本文提供了一个开源程序,以将推算过程自动化。
如果急于看效果,可以
想自定义参数,则可以:
这个程序还会记录每个请求被执行的起止时间,你可以利用它来验算
…
默认情况下执行时间会被直接打印到控制台,但你也可以扩展实现自己的记录展现工具。具体方法是,
你也可以直接通过公式来计算性能。
服务端眼中的RT:
客户端眼中的RT:
若 ,
若 ,
则令, (整除), 且(取模)
得
前面一直在做定量分析,现在可以搞一下定性分析了:从数据中找到可以辅助决策的结论。
我们可以让并发数持续升高,同时观察服务器/客户端眼中性能的差异,以及同一性能指标在不同过载保护机制下的差异。
服务端处理能力:
第1个线程数阈值 |
10 |
第1个线程数阈值前的单个请求处理时间 |
10ms |
第2个线程数阈值 |
20 |
单个请求处理时间函数 |
放大下面两条曲线:
在服务器眼里,保护越强,则性能越好
放大下面两条曲线:
本文给出的程序和公式可以帮助你在已知服务端性能的条件下,计算出客户端的平均等待、相应时间。
本文区别了服务器眼中的RT和客户端眼中的RT,并且通过曲线图介绍了不同过载保护机制下性能如何随并发数变化而变化。
不过,本文的推算剧本中,客户端只会发一次请求:若并发为10,则一次性提交10个请求。而现实中的客户端应该会持续不断的提交请求,这时候它们的平均等待、响应时间又是多少呢? 这个问题要结合客户端本身发送请求的速率来计算,我们以后再深入地看看。
高并发应用中客户端等待、响应时间的推算,及RT/QPS概念辨析
标签:
原文地址:http://www.cnblogs.com/mymelon/p/4989563.html