一般要多少用户才会用到分布式性能测试虚拟用户数

主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
CSDN &《程序员》编辑/记者,投稿&纠错等事宜请致邮
你只管努力,剩下的交给时光!
如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件。而上帝在努力创造出更大更傻的傻瓜。目前为止,上帝是赢的。个人网站:。个人QQ群:、
个人大数据技术博客:
作者:聂永,新浪微博技术专家。负责移动端消息应用架构底层基础设施维护和优化等,目前致力于推广性能驱动模式推动系统健康发展的理念。
本文为原创文章,未经允许不得转载,更多精彩文章请
微博产品后端服务团队在资源受限情况下基于Tsung提供了一套开箱即用的100万用户性能压测工具套件,推动两名能力和经验都欠缺的中初级工程师,不但顺利完成支持海量用户的在线聊天室项目任务,同时保证了该业务系统整体处理性能可控并按照预期方式向前推进。需求 & 背景前段时间我们为微博App增加一个视频直播聊天室功能,这是一个需要支持海量级手机终端用户一起参与、实时互动的强交互系统,建立在私有协议之上、有状态的长连接TCP应用。和其他项目一样,在立项之初,就已确定所构建系统至少能够承载100万用户容量,以及业务处理性能最低标准。当时研发力量投入有限,一名中级工程师 + 一名初级工程师,两人研发经验和实践能力的欠缺不足以完成系统容量和处理性能的考核目标,这是摆在眼前最为头疼问题。聊天室业务逻辑清晰并已文档化,倒不用太担心功能运行正确,除了自我验证外,还会有QA部门帮忙校验。这驱使我们在软件工程角度去思考,如何通过行之有效的手段或工具去推动研发同学项目顺利完成项目性能考核目标。
聊天室会话实例延伸一下,新项目构建之初,自然要关注总体处理性能目标的。但从软件生命周期角度考虑,还应该考虑到系统后续维护和迭代。所谓工欲善其事,必先利其器,因此我们需要提供一个完善的开箱即用、支持海量用户的性能压测基础工具套件,既要能够保证系统处理性能是可测量的,又要能够为每一次版本发布时、常规迭代后再次验证系统性能目标。带着这一目标,下面将逐一展开我们如何构建百万用户性能压测工具套件的过程以及注意事项。
性能贯穿于软件生命周期性能压测工具选择团队所能够支配的空闲服务器数量几乎为零,这是现状。所负责业务线的大部分服务器配置为16GB内存、24个CPU核心左右,每时每刻都在跑着具体的业务。若留心观察,一般晚上九、十点之后资源利用率高,而白天时间CPU、内存、网络等资源大概会剩余30%-60%左右,颇为浪费,如何将这部分资源充分利用起来,是一个需要思索的问题。针对100万用户这样超大容量压测需求,要求每台压测机要能够负载尽可能多的用户量。试想,若一台压测机器承载1万用户,那么就会需要使用到100台,单纯所需数量就是一件让人很恐怖的事情。若是单独为性能压测申请服务器资源,一是流程审批流程较为繁冗,二是因为压测行为不是每时每刻都会执行高频事件,会造成计算资源极大浪费。本着节约资源理想方式就是充分利用现有的空闲计算资源用于执行性能压力测试任务。【众多选择】
当前市面上能够提供性能压测的工具很多,选择面也能很广泛,下面我将结合实际具体业务逐一分析和筛选。
线上引流模式,针对新项目或全新功能就不太合适了,业务层面若需要一定量的业务逻辑支持,很难做得到。JMeter
Java编写,在执行1万个压测用户线程时,CPU上下文切换频繁,大量并发时会有内存溢出问题,很显然也不是理想的选择。nGrinder
图表丰富,架构很强大,堆栈依赖项太多,学习成本很高。
需要额外掌握Python等脚本语言,虽针对程序员友好,不是所有人都可以马上修改。
数十个线程至少占用4GB内存,一台机器上要模拟5万个用户,不但CPU上下文切换恐怖,16GB小内存机器更是远远满足不了。
针对服务器资源充足的团队,可以考虑单独机器部署或Docker部署组成集群,针对我们团队情况就不合适了,想免费做到是不可能的。Tsung
完成同样性能压测功能,却没有第三方库依赖,独立一套应用程序。
虽然所测试服务是I/O密集型,但所占用内存不会成为瓶颈。
可能会触及到Erlang语言,但我们现在工作用的语言就是Erlang,也就不存在什么问题了。其他综合所述,Tsung默认情况下消耗低,可充分利用现有服务器空闲计算资源,线上多次实践也证实资源占用始终在一个理想可控的范围内,具有可让百万用户压测执行的费用成本降低为0的能力,这也是我们选择Tsung的目的所在。【为什么是Tsung?】Tsung是一个有着超过15年历史积累的性能压测工具,本身受益于Erlang天生支持并发和分布式以及实时性的特性,其进程的创建和运行非常廉价,一台机器上轻轻松松创建上百万个进程。其提供一个用户对应一个进程的隔离处理机制,单机支持虚拟用户的用户数量可支持若十万、百万级别,只要机器资源充足(但总体来讲受制于受制于网络、内存等资源,后面会具体解释)。单机计算能力总是有限的,Tsung的目的就是要把多台服务器横向扩展成分布式集群,从而可以对外提供一致的海量性能压力测试服务。协议层,Tsung不但支持TCP/UDP/SSL传输层协议等,而且应用层协议,已支持诸如WebDAV/WebScoket/MQTT/MySQL/PGSQL/AQMP/Jabber/XMPP/LDAP等。默认情况下,开箱即用,凭借着社区的支持,市面上能够找到的公开通用协议,都有相应官方或第三方插件支持。和nGrinder相比,Tsung定位于提供一个强大的性能测试工具,在易用性和强大可扩展方面保持了一个平衡点。基于XML + DSL提供可配置、可编程的能力。比如我们可设置上一次的响应结果作为下一次请求内容,我们可配置多种业务协议、多个业务场景作为一个整体压测等。尽力抽象所要压测的情景吧,你不会失望的。
服务资源占用方面,以单机模拟5万长连接用户为例,有数据正常交互情况下,内存占用不到3GB,CPU占用不到两核,十分经济。
单机5万长连接资源消耗【Tsung的集群架构 & 流程】知其然知其所以然,还是需要掌握Tsung集群大致流程的。这是一种强主从模型,简单流程梳理如下:
Tsung主从架构图
主节点(tsung_controller)通过SSH通道连接到从服务器启动从节点运行时环境;
主节点通过RPC方式批量启动从节点实例(tsung client);
主节点为每一个从节点启动会话监控,控制会话速度,控制每一个压测用户进程ts_client生成速度;
从节点请求主节点具体业务进程,获取会话指令以及会话具体内容;
从节点建立到目标压测服务器的SOCKET网络连接,开始会话;
主节点可以通过SSH通道连接到目标压测服务器,启动从节点,收集数据(可选)。
再深入一些,以MQTT协议为例,每一种具体协议的支持可分为文件解析和会话动作的执行,运作机制不复杂,当我们在需要时可以遵循接口约定实现私有协议支持,也不是难事。
100万用户压测需要多少台机器?要执行100万用户的性能压测,首先预估需要多少台压测服务器才能够满足要求。在Tsung中,一个压测用户对应于一个进程,一个进程默认会打开一条连接到服务器的TCP网络连接。只要内存够用(I/O密集型的应用一般吃内存),基于Erlang开发的应用程序,轻轻松松应对几十万、上百万的进程不是问题。那么我们需要把注意力转移到Linux网络资源上。一台服务器所能够提供网络IP地址数量和内存大小等主要因素,直接决定了能够承载的对外建立的网络连接数,下面我们把主要的影响因素一一列出并分析。
Tsung通用插件调用流程【网络四元组和总连接数】
说到网络连接抽象层面构成元素,针对本机对外建立的一个TCP连接而言,需要使用到本机的IP地址(localip)和端口(localport),以及远程的主机的IP地址(targetip)和端口(targetport),可以使用网络四元组进行呈现一个连接的最小构成:{local_ip,local_port,target_ip,target_port}我司目前所使用的服务器操作系统大多为Centos 6.x版,受制于Linux内核限制,无论目标服务器连接地址如何变化,单机对外建立的连接数量是有限的:总连接数=本机可用IP地址数量×本机可用端口的数量。明白了总连接数的计算方式,那么可以按图索骥,从每一个计算因子上去考虑如何扩大其连接数。
注:若要调试TCP网络四元组,诸位可使用bindp这个小工具:,十分方便。【Linux内核端口数量的限制】
众所周知,在Linxu系统中,端口的数值范围为无符号short类型,值范围为1 ~ 65535。一般来讲1 ~ 1023范围默认只有Root用户有权限使用,普通用户可以使用区间范围1025 ~ 65535,约6万。但你要考虑这中间很多的端口可能被已运行的程序占用,不妨打个折降低预期范围,留有5万左右的可用数值,以作缓冲。
我们可通过sysctl命令确认当前可用的端口范围,以作参考:bash sysctl -a | grep net.ipv4.ip_local_port_range若范围空间太小,比如1024 ~ 35525,那就需要主动扩大一下:bash sysctl -w net.ipv4.ip_local_port_range=""
sysctl -p【扩展阅读:IP可用数量的延伸】
有三种比较经济方式可扩展IP地址可用数量。第一种,针对Linux内核 &= 3.9的Linux服务器而言,可设置SO_REUSEPORT内核参数进行支持;对外一个连接的四元组,将不再仅局限于本机IP地址和端口两个元素,整个网络四元组任何一个元素若有变化,都可以认为是一个全新的TCP连接,那么针对单机而言可用总连接数上限可以这样计算:总连接数 = 本机可用IP地址数量×本机可用端口的数量×远程服务器可访问IP地址数量×远程服务器可访问端口数量。注:
远程服务器指的是要压测的业务服务器提供了多个访问地址(IP地址:端口)访问,但都指向同一个业务服务接口;
一般而言,一个业务服务只会开放一个IP地址和端口。
第二种方式,使用IP地址别名的方式,为本机绑定额外的可用的IP地址:bash ifconfig eth0:1 10.10.10.101 netmask 255.255.255.0注:所绑定的IP地址一定是可用的,否则会导致压测机和被压测的服务器之间无法成功建立连接。第三种,可用考虑使用IP_TRANSPARENT(Linux kernel 2.6.28添加支持)特性支持。在你内存足够大的情况下(比如拥有64GB ~ 128GB内存),假如压测机A的IP地址为10.10.9.100,公司内网有一个IP段10.10.10.0暂时没有被使用,你可以通过ip route工具设置一台机器占用完整一个IP地址段支持。压测机需要为物理网卡eth1添加路由规则,以便能够正常处理来自新增IP段的往返数据包:bash ip rule add iif eth1 tab 100 ip route add local 0.0.0.0/0 dev lo tab 100同时需要在被压测的服务器上添加路由规则,方便在发送响应数据包时候能够找到被路由的接口地址:bash route add -net 10.10.10.0 netmask 255.255.255.0 gw 10.10.9.100这样一折腾,压测机A的可用IP地址就多出来250多个全新的IP地址了。
注:其实,还可以虚拟若干个Docker实例达到这个目的。 有兴趣的同学,可以进一步参考:Tsung笔记之IP地址和端口限制突破篇,以便获得更多资料支持。【内存因素】
针对大部分应用而言,Tsung默认网络堆栈发送和接收缓冲区都是16KB,完全够用了。一个网络连接 = 一个用户 = 一个进程,每进程业务占用约10KB,粗略算下来,一个不太复杂用户逻辑上内存占用不到50KB内存。
按照这个方式计算,1万用户可占用500M内存,单机要支持6W用户,再加上程序自身占用内存,整个Tsung实例大约会占用4GB内存。实际上测试中,在每台压测机分配5万用户情况下内存使用情况,可以见图2。【注意文件句柄】
一个网络连接占用一个文件句柄,可用文件句柄数一定要大于对外建立的连接数。可使用ulimit查看限制的数量:bash ulimit -Sn ulimit -Hn若此值太小,根据实际情况调整,设置大一些,比如下面设置的30万连接句柄限制,大于当前服务器日常对外提供的连接数峰值 + 压测从机对外建立的连接数,有缓冲余地,可轻松应对大部分任务:bash echo "* soft nofile 300000" && /etc/security/limits.conf echo "* hard nofile 300000" && /etc/security/limits.conf还需要关注一下当前服务器总的文件句柄最大打开数量限制:bash cat /proc/sys/fs/file-max此值不能够小于上面所设置的nofile的值,否则需要大一些:bash sysctl -w fs.file-max=300000 sysctl -p【百万用户压测机组成】说完影响因素,现在我们可计算一下,要压测100万用户,理论上需要多少台服务器支持:
每一个IP地址可以支持6万个TCP连接同时打开,那么100万个呢,100万/6万 ≈ 17个IP地址就够了;
1万用户大约占用500MB内存,100万用户大概将占用500MB×100万 / 1000MB ≈ 50GB内存。
总之理论上,一台64GB内存服务器 + 17个可用IP地址,可以单独完成100万用户的压测任务。
注:我们忽略了CPU资源的需求,一般压测是I/O密集型,所耗费CPU资源不是很多,但也要小心,有时需要降低或关闭掉在压测端进行一些高频的数据校验行为。理论和现实总是有差距存在,要做100万用户的压测,如上所述,我们没有大量空闲服务器,有的是若干16GB小内存、单一内网IP地址的线上服务器,需要因地制宜:
留有缓冲余地,每一台压测机平均分配5万个用户;
1台服务器用作压测主机;
20台线上服务器作为压测机。
提前计算和准备好压测使用的服务器,下面该进入设计业务压测会话内容环节了。设计业务压测会话内容紧密贴合业务设计压测,会话内容将是需要考虑的重心。【压测连接信息】
怎么填写压测连接服务器地址、压测从机,根据Tsung手册操作即可。篇幅所限,不再赘述。若是压测单台业务服务器,用户每秒生成速率需要避免设置过大。因为业务型服务,一般以处理具体自身业务为先,在用户每秒产生速率过快情况下,针对新建网络连接的处理速度就不会太快。比如我们实践中设置每秒产生500个用户对线上若干台服务器压测,可避免因为产生过快影响到线上其他具体业务。
实践压测环节中,可能需要考虑很多的事情:
会不会突然之间对LVS网络通道产生影响,需要和网络组同事进行协调;
会不会因为突然之间的压力导致影响到其他现有服务;
一般建议,非封闭的网络环境下将用户每秒压力产生速度设置小一点,保险一些。
【设计压测会话内容】
压力测试会话内容的编写,有三个原则需要注意:模拟、全面和强度。我们在设计压测会话时,一定要清楚所开发系统最终面向的用户是谁,其使用习惯和特征分别是什么,一定要尽可能的去复现其使用场景。其次,需要模拟的用户会话内容要全面覆盖用户交互的各个方面,比如聊天室项目中,一个用户从加入房间,中间流程包括点赞、打赏、光柱、发言等行为,中间间隔的心跳等,最后可选择的退出行为,其业务场景,完整的体现在编写的压测场景中了。另外,针对业务场景特点,还针对每一个具体的行为,还要考虑其执行次数等,简简单单走一遍流程,也就失去了性能压力测试的意义了。下表是在压测聊天室这个业务时压测会话,包含了一个终端用户的完整交互。安装和部署Tsung安装部署要求简单:
所有压测服务器上安装有同样版本的Erlang和Tsung
服务器之间SSH通道需要设置成免密钥自动登录形式
这针对一般的机房环境是没有什么问题,但网络环境是很复杂的,问题总是会多过设想。【SSH不可用时的替代方案】
但SSH通道会被系统管理员出于安全考虑禁用,导致Tsung主节点无法启动从节点,无法建立压测集群。我司机房网络环境就是如此,既然SSH不可使用,那么需要寻找/编写一个替代者。一般情况下,Tsung主节点启动之后,从tsung.xml文件中读取从机列表,进而启动:erlang slave:start(node_slave, bar, "-setcookie mycookie")然后被翻译为类似于ssh HOSTNAME/IP Command命令:bash ssh node_slave erl -detached -noinput -master foo@node_master -sname bar@node_slave -s slave slave_start foo@node_master slave_waiter_0 -setcookie mycookie这很好解释了为什么压测节点之间需要提前设置SSH免密钥登录了。SSH为C/S模式,SSH Server是默认监听22端口的一个守护进程,等待客户端发送命令,解析执行,然后返回结果。明白了这个道理,我们可利用反向Shell机制打造一个SSH替代品。首先我们需要在一个从节点上启动一个守护进程:bash ncat -4 -k -l 39999 -e /bin/bash &主节点作为客户端,比如我们想查询远程服务器主机名:bash echo hostname | ncat 10.77.128.21 39999一点都不复杂吧,但实际上还有很多的工作要做,比如自动断开机制等,我已封装了rsh_client.sh和rsh_daemon.sh两个文件,可参考,不再累述。
问题来了,如何结合Tsung使用呢?第一步,在所有从机启动守护进程:bash sh rsh_daemon.sh start第二步,需要在Tsung启动时使用-r参数指定自定义的远程终端:bash tsung -r rsh_client.sh -f tsung.xml start总之,这个SSH终端替代方案,已经在良好的运行在线上实际压测中了,图6为其部署结构。
注:其实不仅仅是替代,还可以在其上增加一些资源监控功能,我们已经这样干了。【IP直连特性支持】
Tsung还有一个使用不便的地方,从机必须配置主机名,用于主机启动从机实例:
在主机名没有内网DNS解析支持情况下,需要在/etc/hosts文件中手动配置主机名和IP地址映射关系,若是集群很大,维护成本高。如何办呢,我增加了IP直连特性支持: ,需要时检出编译即可使用。
这样压测从机可以直接填写IP地址:xml
weight="1" maxusers="50000" host="client20"&
value="10.10.10.20"&& &其次,在Tsung启动时需要指定-I参数,并填写压测主机IP地址(可以通过Linux代码自动获取):bash tsung -I 压测主机IP地址 -r rsh_client.sh -f tsung.xml start这样改造之后,让Tsung分布式集群在复杂网络机房内网环境下适应性向前迈了一大步。性能压测流程驱动压测之前,我们一般需要关注哪些东西呢,其实大家做法差不多,可以列一个清单:
添加计数器,可以发送到计数收集服务器,报表显示等;
核心逻辑做好日志记录,但日志记录过多时,可能也会成为瓶颈,需要取舍日志等级等;
区分核心模块和非核心模块的在资源紧张时是否需要区别对待等。
压测中,大家一般都是紧密盯着各项报表,查看服务器各项资源开销等。有一点需要强调的是,尽量作为终端用户一员,亲身参与进去,这样才能够切身体验并切切实实感受到此时服务的质量。压测后,复查各项报表,查看错误日志,结合刚才自身的体验等,认真思考修改问题,然后继续下一轮压力测试啦。小结如上所述,我们在没有空闲服务器情况下因地制宜,充分利用服务器空闲计算资源运行Tsung(有所增强、修改)分布式压测集群,让整体费用成本接近于零,同时也使之成为一项基础工具套件,为研发的同学提供足够多的支持。
在这一利器推动下,保证了我们整个聊天室项目的处理性能能够按照预期方式向前推进,有时还会有一点小惊喜:
系统处理性能,由项目之初单机服务1万用户,优化到单机处理50万用户的飞跃;
从上线之初服务支持50万用户,到后面支持1000万;
项目日常迭代,及时避免并修正了因额外功能引入的系统崩溃隐患;
激发了技术创新,期间收获了3项技术创新专利;
勤奋有心的同学,虽然经验欠缺,但被推着不停的发现问题、思考、解决问题,你可以看到他们成长的轨迹。
虽然看上去这一利器功不可没,但工具就是工具,关键还要看使用的人,是否能够一直坚持进行下去,是否可以贯穿于整个研发周期;但知易行难,需去除惰性,坚持下去,形成一种习惯,成为日常的业务流程(如图7)的一个组成部分,否则只能是摆设。
性能压测驱动另外,希望能够给同样境遇的同学提供一种思路,或受限于SSH不可用而放弃搭建Tsung集群,或因地制宜需要稍作定制满足特殊业务,或直接使用我们开源增强版Tsung避免走弯路,或者直接使用Docker等。总之使用Tsung做海量用户的压测,它不会让你失望的。订阅程序员(含iOS、Android及印刷版)请访问
订阅咨询:
在线咨询(QQ):
电话咨询:010-
更多消息,欢迎关注“”博客访问: 2918081
博文数量: 272
博客积分: 11197
博客等级: 上将
技术积分: 6826
注册时间:
认证徽章:
@HUST张友东
work@taobao
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: LINUX
近半年在做分布式系统开发的同时,也做了不少的测试工作,软件工程教科书上描述软件项目的流程,基本上都会提到单元测试、集成测试、压力测试等名词,但对这些词汇一直停留在理论认识阶段。研究生阶段做的项目,因为要求不高,基本上也没做什么测试工作;去年在实习的时候,因为时间有限,主要接触单元测试和系统功能测试;直到现在才把这些词汇都近距离的感受了一下。
分布式系统的开发工作通常会被划分成多个模块,由不同的开发人员分别编写程序,所以代码的单元测试工作通常是针对单个模块进行的。如果模块是独立的,并且功能集足够小,单元测试是很容易做的,构造一组case,尽量覆盖所有的分支基本上就OK。但实际上分布式系统里很少有完全独立的模块,大部分的模块都会跟其他的模块有依赖关系或是网络通信等。
对于有依赖的模块的单元测试,理想情况下,依赖的模块都已经准备好,并且被测试过没有问题(这个实际上是做不到的,而且模块间有时还会存在相互依赖的情况),这种理想情况会严重影响开发效率,使得有依赖的模块就只能串行开发测试。另外,如果依赖的模块在安装、部署上需要花费很长的时间(比如是一个配置比较麻烦的server),那么每次单元测试都需要把server部署起来,测试成本是很高的。
实际单元测试的过程中,我们经常会把依赖其他模块的地方用简单的代码代替,也就是做mock。最直观的mock方式就是通过宏来控制,即如果是以DEBUG模式运行,执行某段简单的代码(mock),如果非DEBUG模式运行,则执行实际的代码逻辑。比如通过下面一段代码把“从网络上获取数据”在DEBUG模式运行时替换为“从本地内存获取数据”,那么在执行单元测试时,我们就不需要依赖网络的对端来提供数据,从而方便的测试代码逻辑。而实际fetch_data_from_network()的测试可延迟到功能测试阶段。
#ifndef DEBUG_MODE
fetch_data_from_network();
fetch_data_from_local_memory();
使用宏来控制有时会使得代码读起来很混乱,如果是使用C++开发(或其他面向对象编程语言),更好的方式是借助多态的性质来做mock,如下面一段代码,DataManager是一个负责管理数据的类,它需要从网络上其他的服务里获取数据,MockDataManager是一个继承自DataManager的类,它从本地内存获取数据,在测试时,我们可以将DataManager的实例换成MockDataManager的实例来运行(必须是指针或是引用),这样思路跟前面的思路其实是一样的,只不过借助多态,更清晰明了,需要做的事情更少。google test和google mock是开源的测试、以及mock框架,使用他们会使你的测试工作更简单,更有趣。
class DataManager {
DataManager();
~DataManager();
virtual int fetch_data()
fetch_data_from_network();
class MockDataManager : public DataManager {
virtual int fetch_data()
fetch_data_from_local_memory();
测试久了之后,你会发现测试的工作量往往跟代码结构的设计有很大的关系,如果代码结构本身毫无章法,再加进去一堆为单元测试而写的代码逻辑,只会令代码看起来更加糟糕;如果设计之初就考虑测试需求,尽量把业务与逻辑层次分开降低模块间依赖性,把可能需要mock测试的地方设计为虚基类等,在做测试的时候需要做的工作就会很少,而且测试新增代码不会打乱现在的代码逻辑结构。
集成(功能)测试
完成单元测试仅仅只是一个开端,做好单元测试是开发人员对代码负责任的表现,一旦模块间有依赖,单元测试做得再好,到了集成测试阶段,问题还是少不了的。集成测试阶段需要把多个模块组合起来一起测试,原来mock测试的地方,现在要玩真的了,但一旦单元测试做得足够充分,在集成测试阶段如果发现问题,那就能很快定位出一定是模块间通信的时候出问题了,测试效率就会非常高。试想两个开发分别开发了客户端模块C和服务器模块S,在完全没有单元测试的情况下,CS组合起来测试,C发送请求给S,请求没有正确执行,这时错误可能在C发送请求开始到接受反馈路径上的任何一个地方,定位问题的难度可想而知,而且在一条长路径上,要保证测试覆盖率的难度也会成倍增长。在集成测试阶段,我们主要关注在功能的正确性上,因为对于异常的case(比如输入不合法等),大都在单元测试里已经完成了。
在功能测试后,发现所有的测试结果都符合预期了,似乎一切都正常了,但这些远远不够,在无压力的情况下,很多代码都是“正确”的,但一旦压力打了之后,这些代码可能就有错误了,在压力测试阶段,要模拟各种恶劣的场景。比如在一个分布式系统里,一个客户端访问时服务正常,十个、一百个、一千个并发访问时呢? 可能出现某段代码因为存在内存泄露而OOM,某些地方出现数组访问越界而coredump等等,总之,在这个阶段,千万不要心软,尽可能用上“十大酷刑”,尽早把潜在的问题逼出来。
分享下我前段时间做分布式文件系统压力测试的两个例子。(1)在并发访问量很大很大时,客户端的请求会出现少量超时请求,调查后发现是在某个失败场景下,服务器没有给客户端回包导致的。(2)写入的大量数据后做读取验证时,发现有小部分请求读到的数据与写入的数据内容不匹配,调查后发现是在极少的文件更新场景下才会出现的bug。
性能测试针对性很强,在系统测试之初,对系统的某些指标都是有预估的,期望他们能达到某个水平,满足某个业务的需求。性能测试阶段首先是要验证系统是否能符合期望值,其次还要发现系统瓶颈所在,并不断改善优化。对于一些通用的性能指标,推荐使用一些广泛被使用的工具(测出的数据能被认可,并且方便交流),比如测试文件系统的性能指标,使用IOZone, IOMeter等,测试web服务器使用loadrunner,AB等工具;只有实在没有现成工具可用时,才自己编写测试工具。
系统一旦上线运行后,肯定会不断暴露出一些测试没有覆盖到的问题或是实现时考虑欠缺的问题,刚开始bug较多,随着不断修复bug及时间推移,bug数量越来越少,最终到达一个稳态。修复bug本身通常很简单,但有时在修复bug时,由于考虑不周全,或是“手抖了一下”,可能会引发新的bug,这时就是回归测试大显身手的时候,每次修复完bug,就对系统做一次全面的回归测试,没有问题才上线新版本。是有成本的,但对于比较大的项目(通常是迭代式开发的),修改代码通常都是“牵一发而动全身”,回归测试必不可少。
回过头再想想经历的测试过程,我发现(1)单测不充分导致后期测试成本高的问题在分布式系统中表现尤为明显;(2)尽可能开发自动化测试工具代替人肉测试,即使后者可能看起来花的时间更短,但实际上工欲善其事必先利其器,武器锋利后(可复用),测试会越来越简单;(3)尽早做测试,问题越早被发现成本越低。
阅读(5470) | 评论(3) | 转发(1) |
相关热门文章
给主人留下些什么吧!~~
你这篇文章也是用markdown写的吗?包括代码部分
请登录后评论。

我要回帖

更多关于 性能测试 的文章

 

随机推荐