前言:之前一直做的软件质量工作,有过一些经验和一些不太成熟的思路,尽管与现在从事产品运营不同,但无论是内涵还是联系,都是非常紧密的,无论如何,我都会继续关注产品的质量问题。
上周跟一朋友阐述性能中并发的概念,叽里咕噜一大通,完了兴致勃勃地让她总结一下,她说了一句:感觉你研究的东西太初级,并发这种概念,太简单,没什么好说的。我听了差点没晕倒,估计她也晕了,真是失败。
并发真的这么简单?性能真的如我们所理解的那样?
也许并不像我们想象的那么简单,之所以我们去探究这些基本的概念,是因为在实际的工作中,我们发现,很多问题到最后才发现,根源在于概念没有统一,抑或没有理解,而无论作为研发人员,还是顾问、销售人员,我们除了自己理解,还需要与客户交流沟通,因此,深刻理解并能通俗易懂的表达出来是非常重要的。
由于软件性能的范围比较大,我们将选取几个典型的问题进行探究,相关概念的理解与分析将逐步进行公开。
● 如何考察性能
这个问题相信很多同事都了然于心了,基本都有自己的理解,我们也很少接到不懂性能的反馈,但很多人甚至包括客户,都把响应时间或者并发用户作为衡量性能的惟一依据,支持10000并发?性能好!响应时间1秒?性能好!有些时候我们也会接到客户一些要求,让我们哭笑不得,某次一客户就要求我们的产品支持10000并发,有点汗,哈哈。
实际上性能是一项工程,严格地说,性能是在某一个特定环境下,系统所表现出来的最大事务处理能力。如果我们将这个问题细化,性能取决于具体环境,取决于系统架构,取决于软件与服务器的优化等等,也就是,我们所提供的内部测试报告是具备一定的前提的(在一定的网络或硬件环境下),如果我们的架构是包含了10台机器的集群,而客户方提供的却是2台PC机,这种条件下还要求测试结果保持一致,就有点为难了。
尽管性能有很多范围、指标、概念,比如响应时间、吞吐量、并发用户、软硬件负荷等等,但对普通用户来说,并发用户数与响应时间这两个概念还是最为直观与普通,认可度也最高,搞清楚这两个概念非常重要。后面我们会逐步阐述其他概念。
● 理解压力
在谈起并发这个概念之前,我们先来说说压力,对系统而言,性能问题归根到底,都会体现为实实在在的压力。因此,我们一般说的“你这个系统的性能最高能到多少?”,其内在含义指的就是“系统所能承受的最大压力是多少”。
那么压力究竟是什么呢?
我突然想起天天坐的地铁,没有比坐地铁这件事情更便于形容性能与压力了,哈哈。话说我每天在立水桥南上地铁,绝对是考验体力耐力心理素质的事情啊(说岔了)。
我们可以把一班地铁列车看成是一个被测的系统,对于这个系统而言,其压力显而易见,就是列车中所有的人,比如北京地铁5号线,每列车的定员人数是1424人,折合每节车厢237人(当然包括站着的),而最多容纳是1820人,折合每车厢303人,这个总承受人数。
其实就是系统(也就是列车)的最大设计承受压力(也就是吞吐量了),当然,北京地铁比较变态,超员现象比较严重,我每天占用的面积还不超过10平方厘米(脚踮起来了),实际最大负荷估计超过2000了。对列车而言,超过最大负荷是比较危险的,要么是拉不动(这个估计可能性不大),要么人挤坏(君不见每天争吵哀嚎无数)。
如果超出设计负荷值,系统就会存在危险,危险是多方面的,因此,一般的,系统应该具备超出负荷的处理预案,对照到地铁,高峰时期就会进行限流。
搞清楚这个问题后,再来看看常规的系统,就好理解了,系统的压力是什么呢?压力是对被测系统而言的,只要系统在处理事务,就有压力,这种压力不仅仅体现在网络上(数据的吞吐),还体现在服务器上(如CPU、内存等),因此,我们不要混淆了吞吐量与压力的关系,应该这么说,在一些web系统上,吞吐量可以在一定程度上反映系统承受的数据压力。
另外,我们需要清楚,压力不等于性能,压力只是检验性能的一种手段,对一个性能良好的系统,在一定的压力下,应该可以保持正常运转,如果超过负荷,则应该分流或化解压力,这也是我们需要检验的。
● 理解并发
说完压力,我们已经知道,压力其实就是一种作用力,当然,还可以理解为一种量的度量,比如列车的承载数,既然有量,就肯定有速度,承载总量(吞吐量)是一定的,但速度却是变化的,我们早晚高峰的时候去乘地铁,当然是拥挤非常,但如果你晚上11点去做地铁,我可以很高兴地告诉你,你还会有座位!
原因在于,早晚高峰时坐地铁的人多,深夜时坐地铁的人少(这不是废话吗)。我们再来想想,高峰的时候可能同一时间挤进门的人很多,基本上门有多大,同时挤进去的人就能把门给塞满。
那么这个并发(虚拟用户)是什么呢?
并发是有场景条件的,要看我们考察的是什么事情,我们再来想象一下地铁,在整个地铁大厅里(包括列车),有刚刚进站的,有正在买票的,有正在登车的,有坐在车上的,还有闲逛的,这么多人,但对列车有压力的,其实就是已经在车上的这些人(包括挤车的),如果我们考察性能的系统就是列车,很显然,重点关心的就只需要看看车上现有的这些人。
再次强调,并发跟考察的具体场景是有关系的,即并发做什么,并发这个词,原始的翻译是concurrent,意为同时发生的,或同时存在的。至于同时做什么,要看我们定义了,同时在地铁大厅里,同时在地铁上,同时在挤地铁,考察的事情不一样,并发的意义就不一样。
对地铁这个系统而言,每个时间都有新来的人,也有走的人,大家做的事情基本都相同,乘地铁。假定某个时刻地铁大厅中有10000人,检票口候车的有100人,刚刚开走的地铁上乘有2000人,那此时对考察的系统(列车)而言,并发就是2000人,而如果考察的是检票处,则并发为100人,同样,如果考察的系统是地铁大厅,那此时的并发就是10000人。这种并发我们一般称之为“广义并发”。
广义并发有点类似与通常我们所说的在线用户,但存在关键的区别,即并发用户针对的是某一件事务,譬如注册、登录、上传、浏览等,而在线用户是一个很泛的概念,一般包括前面所述的所有事务,可以理解为一个事务集合。
在性能的理论中,还有一个概念,simultaneously,翻译为同步的,当前,为方便计算,我们一般把“同步”理解为“同1秒”,也就是说,这个同步的就是单位时间内发生的数量。也即我们通常所说的“狭义并发”。需要注意的是,实际的测试中经常会遇到被测事务响应时间低于这个1秒的单位时间,此时的并发计算仍需要按1秒计算,具体参见“我们的定义”中的说明。
很多时候,我们(特别是客户)往往搞混了这两个并发的概念。对系统来说,广义的并发实际上是在一个时间内操作事务的虚拟用户,而狭义的并发指的是单位时间内向系统发起请求的虚拟用户,前者是“存在”,后者是“请求”,勿容置疑,压力不仅仅受成功发出请求的用户带来的压力,同时也受“存在”的用户影响。
换种理解方式,并发考察的是系统的处理能力,最多能支持多少用户同时处理某件事务,而不是压力发出端发出的请求。
除此之外,并发作为一个量化的指标,是对应着具体的取值的,因此,很多系统会去寻求最大并发,实际上,我们来回顾5号线的承载力的例子,核定载客1424人,这种情况可能考虑到乘客的感受(还算舒服,站着也算,哈哈)
● 理解我们的定义
在我们已经做过的很多测试中,都有并发这个概念,当然也包括我们很多开发人员,所谓的并发是怎么定义的呢?
客观的说,我们的定义比较接近于“广义并发”,但有所不同。这与我们的考察对象(web系统)、衡量事务(通常我们衡量的都是单个事务,很少把多个事务放在一起处理,原因在于尽量避免事务的耦合性所带来的影响)有关,具体到地铁的例子,如果我们考察的系统指“地铁大厅”,那么我们所谓的并发一般通常指同时进入地铁大厅的人。而如果我们考察的系统指“地铁列车”,那么我们所谓的并发则指同时进入站台的人。
在实际的产品测试中,比如我们在测试IDS登录的时候,如果说,支持800并发,其涵义为“支持800个虚拟用户同时进行登录操作”,需要说明的是,这个同时并非指同一秒,要知道,并发本身是没有单位的。在800并发下的结果如何,要看响应时间,这个问题本文不进行仔细阐述。如有兴趣可以参考相关资料。
测试中,我们也会考虑“狭义并发”的情况,但狭义并发需要考虑到被测系统的入口,比如,假定地铁总共有10个入口且全部开放,每个入口只能容纳1个人进出,则“狭义并发”下最大值就是10?不一定!因为我们还没有考虑速度问题,前面提到,狭义并发的单位是秒,如果每个人通过每个入口的耗时就是1s,则最大“狭义并发”值就是10,如果通过的时间少于1秒呢?还是按1秒算,比如还是这个情景,乘客通过入口的耗时假定为0.1秒,则最大狭义并发就是10/0.1=100了。
简单点说,我们可以这么理解实际工作中的并发,被测的事务总得有人(其实就是虚拟的用户)来做,对吧,同时允许多少用户来做这件事情呢?这个多少用户就是我们需要的并发值。
● 如何估算并发
那么我们如何来估算这个并发值呢?
在此我们需要作出说明,一般我们需要的数据应该来自于实际数据(比如系统日志的记录),这样最可靠,只有当系统新启动且无任何数据参考的时候我们才需要进行估算。
比如我们测试地铁大厅的性能情况,该如何去估算当乘客进入大厅时,地铁大厅的性能呢?下面以笔者经常乘坐的地铁5号线立水桥南站为例进行估算,过程与数据仅供参考。
假定每天从该站乘坐地铁的人数为5万人次,每天的早高峰为7-9点,晚高峰为6-7点,根据8/2原则,80%的乘客(人次)会在高峰期乘坐该站的地铁,则平均每秒到达地铁检票口的人数为(50000×80%)/(3×60×60) = 3.7~=4人,当然这个4人不能作为计算所用的并发值,因为对此时的受压入口检票口来说,4只是每秒到达的压力(即请求)数量,考虑到安检、入口关闭等因素,实际堆积在检票口的人数可能要大于这个数目,假定每个人需要3秒左右才能入站,则实际并发应该为(4人/秒)×3秒=12。当然我们必须指出,这种方法得到的情况并非极端值,因为即使作为早晚高峰,人数的分布也不是平均的(具体情况需要根据实际数据进行分析),但对大部分系统的大部分场景,我们可以用(用户总量/统计时间)×影响因子(一般为3,为经验系数)来进行估算。
实际上,还有一种估算方法,而这种估算方法为国内众多书籍、文章反复转载,其来源与Eric Man Wong在2004年公布的一篇“论文”《Method for Estimating the Number of Concurrent Users》,其核心公式如下:
C=nL/T
其中,C代表在线用户,n代表执行事务的用户总数,L代表每用户的平均在线时间,T为待统计的总时间,依旧以地铁入站的情况进行估算,依旧考虑8/2原则,即n为50000*80%人,T为3小时,L即我们在地铁中停留的时间(从进站到上车),假定为5分钟,因此得到的公式为:
C=(50000人×80%×5min)/3×60min = 1111
并发数是1111,比前面一种算法要高的多,这是为什么呢?
实际上,后面这种统计方法是由一定的局限性与适用范围的,对其统计的每个并发用户而言,每个用户所在线的时间(如上面的5min),并不一定是我们所需要的场景耗时,该5分钟应该是整个大场景(如从进站到离开),而我们通常所使用的场景往往包含了一连贯的子场景,如进站、等待、上车等,因此,如果我们测试的场景是某一个具体的动作,不建议采用这种公式(当然,如果单独为每个动作估算时间也是可以的。)
从本质上来说,两种公式的统计,结果都是一样的,关键取决与统计口径。
极限的问题也是我们需要考虑的,数据的估算往往是一个大的工程,涉及到很多复杂的情况,比如用户的进入与离开,人流异常等,因此我们考虑的多为常规的情况,在一些特殊的情况下,用户的峰值往往要大很多,此时需要去对极限情况下进行估算。
此时的目的在于检查系统的极限承载情况,如列车最大承载2000人,站内极限承载10000人是一样的,超出这个极限,就需要采取一些紧急措施,比如限流(对应到普通的系统,就是设置最大连接数,超出的必须等待)之类。
这种值的计算,不可能给出准确值,可以根据实际情况,协商而定,比如把经验系数更改为5,这种情况下,如果有日志或者统计数据予以支撑,会更加精确。
● 回答客户的疑惑
面对客户,经常需要去解答一些问题,常见的几类疑惑如下:
1、客户坚持要求并发2000,怎么办?
这个问题非常关键,即上面所谓的阐述只是为了让大家对并发等概念有个大体的理
解,但我们的工作重心不是一来就跟客户讲理论,而是合理、有效、迅速地完成项目,因此,特别是一些项目的咨询阶段,如果客户坚持提出达到某个并发要求,我们首先需要看下这个情况产品能否支持,如果不支持,通过修改架构(比如增加服务器,公司的大部分产品都支持集群)来完成,如果还是没法达到要求,我们再来跟客户交流,从客户能理解的方式,从客户的角度去计算并发,最后得到认可就行了。当然,解决这些问题,需要我们对公司的产品性能基本比较了解(可以通过产品的性能测试报告来了解,质保将来会考虑出台所有产品的性能指标集合供参考),如果难度还是很大,可以申请质保的支持。大家一起去解决这个问题。
2、你们的系统能支持10000并发吗?
一些客户经常提出非常高的并发要求,此类客户通常对性能并不了解,或者之前有客户对其做了错误的解释,此时我们需要解释我们测试并发的概念:同时向服务器发出请求的虚拟用户数。(而我们通常会采用严格的方法进行场景测试:即采用集合点的方式进行操作。这种方式也即前面介绍的狭义并发的概念。)
另外,并发值需要考虑实际情况,需要根据实际的需求进行计算,与此同时,并发的影响因素并非仅仅是软件本身,还有网络、架构等等,TRS的产品性能测试往往给出单位机器的性能,用户可以根据这个基础值来构造实际架构。
3、你们的系统怎么才支持200并发?
并发的概念在于同时在处理某一件事情,而且系统一直保持这样的一个强度,并不是说总共只有200人,另外,我们测试的一般是单机,也就是说,如果更好的性能要求,可以通过集群的方式来获得更优的结果,目前TRS的产品基本都支持集群的部署架构。需要注意的是,并发的支持除了软件本身,还受到网络、服务器性能等多方面原因的影响。
4、是否可以使用每秒处理事务来衡量。
性能测试的衡量指标除了响应时间,还有吞吐量、每秒点击数、每秒PV、每秒事务处理能力等,因此我们可以通过多种方式进行衡量,在更大意义上,各个指标间也存在一定的内涵联系,结合起来考虑更能够检查系统的性能。但受制于一些客观原因(如定制),在之前的报告中,指标衡量存在一定的限制。
5、响应时间与并发、压力是什么关系?这么操作的响应怎么才6秒,太慢了,你们的产品性能不行啊!
一般的,一定的并发下将对系统造成一定的压力,而对每个并发(用户)而言,所体现出来的性能多是直观的响应时间,在环境一定的情况下,响应时间越快说明系统性能越好。但此处需要清除一个问题,假定一个用户获取的响应时间是5秒,这5秒都在对系统产生压力吗?
后面这个是一个有趣而有意义的问题,我们知道这个响应时间是从用户发出请求到接收到响应的为止的总耗时,如果我们使用httpwatch之类的工具,可以很清晰的看到时间消耗的分布区间,我们可以把这个问题比作是向墙壁击出一个球,从击出到弹回来的时间即为响应时间。
大家打过壁球吗?打壁球的过程其实就完美的诠释了用户发起请求到接受响应整个过程,可以我们可以把墙壁看作系统,打球者就是用户,球是用户发出的请求,击打一次球包含有三个动作:击出球、球接触墙壁、收到弹回的球。三个过程加起来的总时间就是这个请求(打出一发球)所得到的响应,但很显然,真正对系统产生压力的动作在于接触墙壁的时间,大部分的时间消耗在空中,即球在空中飞行时的时间,而这个飞行时间并不受系统控制,对应到常规系统,就很可能是网络在传输过程中出现了问题。
这个壁球的例子实际上还可以解释一些相关的概念,比如并发就是同时击出多个球,系统(墙壁)所能承受的最大并发压力就是墙壁的面积所能容纳的壁球数量,假定墙壁面积可以容纳1000个球,则墙壁瞬间可以接触的球的数量就是1000个,这个就是狭义并发的概念了,考虑到空中飞行,即将触碰墙壁的球,理论上的广义并发值要高于1000。击球时的力度可以理解为客户端的性能,性能好发球就快,否则就慢,只要系统性能没有达到瓶颈(比如墙壁没有坏),系统的性能是跟客户端呈正比的,即击球速度越快,返回越快。
因此,当遇到客户对响应时间有疑问时,我们需要解释的重点在于,压力在于球接触墙壁的瞬间,但性能测试考核的响应时间确实包含了两次飞行(发送与接受)的时间,而这个时间是受包含服务器性能、网络性能、客户端性能在内的多因素影响的,相信客户可以理解。
● 简单的结论
如果您觉得上面说的东西过于繁琐,以下基本概念可能更适合阅读。
1、并发分为狭义并发与广义并发两种,狭义并发指同一时间点开始做某件事情,广义并发指同一时间段正在做某件事情;
2、并发与被考察的场景是息息相关的,测试中所指的并发一般指同一时间段在做某件事情(被测事务)的用户数,在严格测试的环境下,我们会要求所有用户在同一时间点集合并执行;
3、在线用户与并发用户不是一个概念,在线用户包含了很多非测试事务用户、空闲的客户等,因此不能把在线的用户全计作并发用户,一般的并发用户占在线用户总量在10%~20%左右,当然,这个值仅供参考,实际问题需要实际分析。
4、理论上说并发越大性能越好,但其取决与很多因素,比如网络、服务器数量、服务器性能、系统架构、软硬件优化等,另外,并发的计算需要在需求阶段根据实际情况进行估算,这样得到的结果才是合理的。
5、几个概念的再次说明:
→ 并发用户数:同时在操作被考察事务的用户数
→ 在线用户数:当前被测系统中的活动用户数(包括考察事务与非考察事务)
→ 平均响应时间:每个用户操作事务获得的平均响应时间(算术平均值)
→ 90%响应时间:90%用户平均响应时间在此值范围内(取除去10%极高值后的最大值)
→ 平均事务数:单位时间完成的事务数(如登录、首页读取等)
→ 平均吞吐量:单位时间内的数据传输量
→ 平均点击数:单位时间完成的请求数量
→ PV:某时间段内完成的页面请求数量
====================================分割线================================
最新内容请见作者的GitHub页:http://qaseven.github.io/