为什么要进行性能测试?
什么是好的与坏的性能?为什么性能测试在软件开发生命周期(SDLC software development life cycle)中很重要?
性能不佳的应用通常无法实现企业预期利益,花费了大量时间和金钱,但是却在用户中失去了信誉。
相比功能测试和验收测试(OAT operational acceptance testing),性能测试容易被忽略,往往在发布之后碰到性能和扩展性问题才意识到重要性。
最终用户眼中的性能
性能”是用户最终的感受。性能优异的应用在最终用户执行某项任务时不会产生过度的延迟而引起用户的不满。好的应用不会在登录时显示空屏,不会让用户走神。比如偶然的用户在购物网站上寻找和购买他们所需要的东西时,客户中心不会收到差性能的投诉。
多数应用系统在峰值时性能表现不佳。从高层看,应用由客户端软件和基础设施组成,后者包括了运行软件所需的服务器硬件和网络基础设施。另外有些应用还有第3方服务。任何一个组成部分中出现问题,整个系统的性能就将面临灾难。您可能会简单地认为,为了保证应用性能,观察应用每个部分在负载压力下的运行状况并且解决所出现的问题即可。这种做法往往“太少”和“太迟”了,因此只能是治标不治本。
性能度量
关键业绩指标(KPIs key performance indicators)有服务和效率两种。
基于服务的:衡量应用系统为用户服务的好坏。
- 可用性(Availability): 终端用户可以使用的应用的总时间。可用性很重要,小小的故障也会导致大量的商务上的花费。用户无法有效地使用该应用系统,比如应用不响应或者响应慢到无法接受。)
- 响应时间(response time):一般指系统响应时间。即用户发起请求到收到结果的时间。响应有异步和同步两种。
基于效率的:衡量应用对基础设施的利用。
- 吞吐量(Throughput):应用处理速度,比如一定时间内某个页面的点击数。
- 利用率(Utilization):理论资源的使用率。当1000个用户同时在线时,应用消耗了多少网络带宽及在服务器内存和cpu等使用情况。
性能标准
没有正式的行业标准,但是有许多非正式的标准,试图对系统的性能好坏做出评价,尤其是B/S应用。比如“页面最小刷新时间”从20秒到8秒,现在是2秒最佳。用户和企业都希望系统能够“即时响应”,但现在这样的性能很难达到的。
(Martin et al.,1988)的研究表明:
- 超过15 秒:基本上不适合交互。某些特定的应用,一些用户可能坐在终端等待超过15秒的时间去等待查询结果的返回, 比如公安局的网上预约系统。然而繁忙的呼叫中心运营商或期货交易商,超过15 秒无法容忍的。如果真的发系统就应该设计成可以让用户转向其他的操作,后面异步响应。
- 超过4秒:对于要求用户保存短暂记忆里的会话来说太长,当然交易完成之后,4-15秒的延迟是可以忍受的。
- 2-4 秒:超过2秒很难引起用户的高度关注。买家在输入了她的地址和信用卡号码后等待2-4秒的时间可以接受。然而如果是在早先的阶段,当她正在比较不同产品的差异时,却又是不可容忍的。
- 低于2 秒: 用户需要记住几个响应信息时,响应时间必须很短,如果要记住更为详细的信息,则要求就更高了。
- 亚秒: 思想密集型的工作来说(比如写一本书),尤其是一个图形应用程序,响应时间要非常短才能够保持用户的兴趣和长时间的关注。当艺术家将图片拖曳到另一个位置时,程序必须能够立即响应。
- 马上响应:按键并在屏幕上出现相应的字符,或者用鼠标点击,这种响应必须几乎是瞬时的。比如游戏。
- 由此可见,响应时间临界点是2秒。
糟糕的性能:为何如此普遍?
IT 商业价值曲线
性能问题通常会比较晚才发现,而且越晚发现,解决成本就越高。
实线(计划)表示预期结果。方块表示部署。虚线(实际)表示实际结果,延迟上线,上线后因为性能问题产生负面效果。
性能测试成熟度
Forrester在 2006年对典型应用系统上线后发现的性能缺陷进行了调查:
图中定义了三种性能测试。
- 第一种是救火(Firefighting),发布前很少或从来没有性能测试。所有性能缺陷在生产环境上发现解决。这是最不可取的,却依然比较普遍。
- 第二种是性能验证(performance validation)。公司为性能测试在产品的后期安排了时间,生产环境会发现30%左右的性能bug。这个当前绝大多数公司的做法。
- 第三种是性能驱动(performance driven),生命周期中的每一阶段都考虑了性能, 生产环境会发现5%左右的性能bug。
系统设计阶段缺少性能方面的考虑
设计的时候考虑性能有望产出好性能的应用,至少也能使应用在出现意想不到的性能问题时灵活地能进行修改或重新配置。设计相关的性能问题后期才发现就很难解决,有时候甚至需要重新开发。
多数的应用基于可独立测试的组件进行开发的,组件在单独执行的时候性能可能都不错,切记必须从整体来考虑。这些组件之间的交互必须高效且扩展性好,集成后才会有好的性能。
直到最后一刻才进行性能测试
性能验证模式下,性能测试直到系统发布前才会进行,并且很少考虑到性能测试所需的时间及失败后所造成的后果。可能无法发现一些严重的性能缺陷或发现了性能问题但却没有时间解决。
扩展性
可能忽略了用户的地理分布和规模等。需要考虑如下问题:
- 有多少终端用户会实际使用?
- 用户位于何处?
- 多少用户会同时使用?
- 用户如何连接到应用?
- 后期有多少额外的用户需要访问应用?
- 应用的服务器数量及网络拓扑?
- 将应用对网络容量产生什么影响?
了解流行度
很多公司低估其应用的人气,人是好奇的,系统发布的第一天,你估计1万次点击,结果却是100万次点击,您的应用系统就这样崩溃了!需要考虑高峰访问。
令人震惊的失败:一个真实的例子
在很多年以前,英国政府决定在互联网上公布1901年人口普查的结果。这涉及到大量的将旧文档转换成现代的数字格式文档的工作,并且还需要创建一个应用以供公众访问。
很多希望了解家族历史,24小时之后网站崩溃了。在之后的几个星期里始终无法访问,直到最后重新发布。
性能测试还不规范
目前性能调优的书籍很多,但是对医生而言,最重要的是识别病情,识别性能瓶颈比解决问题有时更难。
不使用自动化的测试工具
不使用自动化的测试工具和自动化:单单使用手工是很难完成性能测试的。
应用程序使用技术的影响
应用程序使用技术的影响:某些新技术不太方便进行测试。
如何选择性能测试工具?
web方面的测试工具比较多。但是非web的,尤其是涉及到加密和压缩的,就很少了,甚至是https,很多工具都处理不好。
性能测试工具架构
常见的性能测试工具架构:
- 脚本:描述用户的活动,支持不同协议。
- 测试管理模块: 创建并执行性能测试会话或场景。
- 负载生成器: 生成负载。
- 分析模块: 分析数据,有些还有自动分析的专家模式。
- 其他模块: 监控服务器和网络性能的同时,与其他软件集成。
选择性能测试工具
选择性能测试工具:
除了HTTP/S支持比较广泛,JavaScript, JSON和 Microsoft Silverlight就不一样了。
- 协议支持
- 授权:比如最大虚拟用户数;能支持的额外协议;附加插件集成和特定的技术栈监控,比如Oracle, Python等,)可以与APM(application performance monitoring)与CI(continuous integration)集成。
- 脚本支持:稍微复杂一点的测试就需要深入脚本。考虑脚本修改的难度;考虑测试团队的技术水平,比如团队如果有python高手,直接用python功能会比具体的工具要强大得多。
- 解决方案与负载测试工具: 有些厂商只提供个负载测试工具,而有些提供性能测试解决方案。解决方案产花费更多,但通常功能更强大,可能包括自动需求管理,自动数据创建和管理,预性能 测试的应用程序调试和优化,响应时间预测和容量建模,APM提供类和方法层面的分析,集成用户体验(EYE)监控,管理测试结果和测试资产等。
- 外包:可以免去工具选型等。但是次数太多的成本太高。
- 其他:基于云平台的测试。节约硬件成本。缺点:次数太多的成本太高,性能指标监控未必方便。程序不稳定时代价很高。
性能测试工具集:概念验证(POC Proof of Concept)
POC至少要有两个用例:读数据和写数据。目的如下:
- 对性能测试工具是否适合目标应用进行技术评估。
- 识别脚本数据要求
- 评估脚本需要的编写和修改时间
- 展示测试工具的容量。
POC检查表
一般不建议超过2天。
- 准备:
- 成功或退出标准,客户已经签字。
- 工具的软硬件准备ok。
- 安装任何需要监控软件的权限。
- 理想情况下保证环境专有性
- 应用技术支持:产品专家。
- 应用技术支持:技术专家(比如开发)可以咨询或者应用中间件级别的架构宣讲。
- 用户帐户:可以安装访问
- 至少两套凭据登录目标应用程序。因为需要并发执行等。
- 两个用例,简单的读和复杂的写。
- 过程
- 录制用例并比较异同,注意运行时和会话数据等。
- 修改脚本,确认用户和多用户模式都可以执行,结果正确。确保脚本无内存泄露等不良行为。
- 交付:
- 通过或者不通过
- 生成了数据需求。
- 脚本开发时间
- 如果是售前,要能说服客户
有效应用性能测试的基础
需要考虑的问题:
- 发布时要支持多少用户?6个月,12个月,2年后呢?
- 用户分布及如何将它们连接到应用?
- 发布时用户的并发? 6个月后,12个月,2年后呢?
回答会引出一些问题, 比如:
- 每个应用层需要的服务器规格及数量是什么?
- 服务器的位置?
- 网络基础设施的类型?
回答不出来没有关系,但是你已经开始考虑容量和扩展性了。从广义上讲,功能需求定义系统是应该做什么,非功能需求定义系统是什么样子(来自维基百科)。在软件测试中,性能测试基于基准衡量系统对性能和容量质量,包括以下内容:
- 项目计划
- 应用够稳定
- 足够的时间
- 代码冻结
- 基本的非功能需求
- 设计合适的性能测试环境
- 设置现实合适的性能目标
- 确定并脚本化的关键use case
- 测试数据
- 负荷模型
- 精确的性能测试设计
- KPI(Key Performance Indicator)
应用准备OK
功能要运行稳定,不能10次运行,2次失败。避免性能测试成为频繁的bug修改实践。功能等问题会掩盖性能问题。要有严格的单元和功能测试保证。衡量标准如下:
- 大量数据(High data presentation):比如大量图片和冗余会话。
- 低效SQL(Poorly performing SQL): 比如下图:
- 大量应用的网络来回:容易导致延迟、带宽限制和网络拥塞等。
- 应用错误:比如HTTP 404,500等。
足够的时间
以下工作需要时间:
- 准备测试环境
- 配置负载注射器
- 识别user case(数天到数周)和脚本化
- 确定和创建测试数据(数天到数周)
- 测试环境安装配置
- 问题解决
代码冻结
不冻结可能会导致脚本失效或不能代表用户行为等。
设计性能测试环境
理论上要与生产环境完全一致,但是很多原因导致不太可能,下面列出部分原因:
- 服务器的数量和规格: 服务器内容和架构难以复制,尽量保持规格一致,以方便提供基准。
- 带宽和网络基础设施:地理位置难以复制。
- 部署层次:建议完全一致。
- 数据库大小:建议完全一致。
也有公司直接在生产环境同时部署测试环境或者直接拿生产环境做性能测试,后者注意不要影响用户,包含数据和服务等。
性能测试的环境类型有:
- 生产环境非常接近的副本:通常不太现实。
- 生产环境的子集,层次一致,服务器规格一致,但是数量有所减少:建议达到的方案。
- 生产环境的子集,层次有缩减,服务器规格一致,但是数量有所减少:最常见的方案。
虚拟化
虚拟化的概念请参考:https://en.wikipedia.org/wiki/Virtualization 和 https://en.wikipedia.org/wiki/Docker_(software) 等。 注意:
- 虚拟机管理程序层有管理开销
- 总线和网络的通信方式不同。前者没有带宽和延迟限制。在网络跨地理位置的情况尤其需要注意。建议虚拟化与生产环境一致。特别注意不要跨层虚拟化在同一机器。
- 物理与虚拟NIC:后者的开销更大。
云计算
可以简单理解云计算为商品化的虚拟主机,它便宜,容易部署。相关概念介绍参见:https://en.wikipedia.org/wiki/Cloud_computing 。
优点:
- 可以生成大量负载注射器。
- 便宜
- 快速
- 可扩展
- 易部署
缺点
- 不及时关闭很贵
- 有时不可靠,比如配置的机器无法启动,IP被墙等。
负载注入容量
单机能模拟的虚拟用户是有限的,特别注意测试机的CPU和内存等使用率不要过载,尽量使用多的机器机进行测试。注意以下几点:
- 负载均衡:一些基于IP分配服务器。所以必要的时候需要使用IP欺骗。
- 用户会话限制:比如一个IP只能一个会话。
其他问题:
- 有些中间件不能用脚本表示。解决办法,从表示层入手;改用瘦客户端;自行开发工具。
- 衡量表示层性能:性能测试通常工作在中间件层。比如想计算用户点击复选框的时间,建议使用前端测试工具。
网络部署模式
广域网的速度通常只有256 Kb左右,网络延迟也比较大。延迟的产生基于光速:1ms/130公里以及交换机、路由器等网络设备和服务器的时延。
如果有必要,可以:1,从WAN进行性能测试;2,测试工具模拟;3,网络模拟。
环境检查表
- 服务器数:物理或虚拟服务器的数量。
- 负载均衡策略:负载均衡机制的类型。
- 硬件清单:CPU的类型和数目,内存,网卡的类型和数量。
- 软件清单:标准版本的软件清单(不包括中间件)。
- 中间件清单。
- 内部和外部链接
软件安装约束
比如安全考虑。
务实的性能目标
目标部分来自服务级别协议(SLA service-level agreement)。无论如何目标必须明确。
一致
一致且尽早介入。
业务
C级管理负责预算和策略决定:
?首席信息官(CIO Chief information officer)
?首席技术官(CTO Chief technology officer)
?首席财务官(CFO Chief financial officer (CFO))
?部门负责人
IT
?开发人员
?测试
?架构团队
?服务提供者(内部和外部)
?终端用户
?IT或运维
性能目标定义
主要包含可用性、响应时间、吞吐量、并发、网络利用率和服务器利用率。
在性能测试中并发是同时在线的用户。要注意并发虚拟用户和并发实际用户不一定是同一回事。估算时需要基于二八原理和峰值等。
吞吐量通常更适合衡量无状态的行为。比如浏览购物时通常不会登录,看中之后才会登录,浏览购物可以认为是无状态的。
响应时间不要随着并发的增加而大幅度增加,可以基于单个用户做基准测试。
网络利用率需要关注数据量、数据吞吐量(可能会导致吞吐量突然下降是容量问题)和数据错误率。
服务器利用率主要关注CPU、内存和I/O(磁盘和网络等)
确定和脚本化关键业务user case
关键的user case一般不会超过10个。
Use-Case检查表
- 记录每个步骤
- 输入数据和期望的响应
- 用户类型:新的或老用户,超级用户,客户,客服等类型。
- 网络:LAN或WAN
- 主动还是被动
脚本验证
基于抓包工具或录制工具书写脚本,然后单用户到多用户调通。注意脚本不要影响到并发的执行,尽量使用不同的用户等。
检查点
业务较复杂时尤其重要。
是否需要登入登出
尽量符合实际情况。
共存
注意共存的应用和网络共享
测试数据
输入数据
- 用户凭据:比如用户名和密码。
- 查找规则:通过客户的姓名和详细地址,发票号和产品码甚至是通配符进行查询。
- 相关文件:比如图片。
目标数据
需要考虑数据容量是否符合规格的大小,数据回滚等。
会话数据
比如token。
数据安全
数据要保密,同时性能测试工具要实现与服务器端通信的加密方式。
性能测试设计
性能测试的类型
1.pipe-clean测试。
2.容量测试。尽量接近用户实际使用。
3.隔离测试。
4.压力测试。退出标准:没有更多的用户可以登录,响应时间难以接受,或应用程序变得不可用。
5.浸泡测试,又叫稳定测试。发现内存泄漏等问题。
6.冒烟测试,只测试修改的部分。注意和其他地方的概念不一样。
pipe-clean, volume, stress和soak test通常都需要进行。
负载模型
负载模型定义了user case的负载分布及并发和吞吐量的目标。通常先基于容量测试,再扩展到其他类型。注意测试数据、思考时间和步长的影响。比如搜索数据分类:
- 小数据模型:具体的产品名称或ID。
- 中数据模型:局部产品名称。
- 大数据模型: 通配符或最小的产品名称的内容。
需要模拟真实情况下各种user case的分布:
吞吐量模型对于已有一个用需要参考Google Analytics或WebTrends,新应用的需要估计。
思考时间代表着延迟和暂停。
步长是循环之间的间隔。
负载注入方式有:Big Bang、Ramp-up、Ramp-up (with step)、Ramp up (with step), ramp down (with step)、Delayed start。注意"with step"主要是为了方便观察。
KPI
服务器KPI
Windows 性能工具。Linux有monitor、top,、vmstat、sar等工具。监控分为业务层、中间件层和系统层等。
通用模板如下:
? Total processor utilization %
? Processor queue length
? Context switches/second
? Available memory in bytes
? Memory pages faults/second
? Memory cache faults/second
? Memory page reads/second
? Page file usage %
? Top 10 processes in terms of the previous counters
? Free disk space %
? Physical disk: average disk queue length
? Physical disk: % disk time
? Network interface: Packets Received errors
? Network interface: Packets Outbound errors
Web和应用服务器层:比如nginx、WebLogic、WebSphere、Apache、JBOSS等。
数据库层:比如MYSQL、Oracle等。MongoDB, Cassandra和DynamoDB可以视为应用设计的一部分。
大型主机层:比如Strobe、Candle
主机层:比如亚马逊的CloudWatch。
网络层:网络错误、延迟、带宽。
应用监控
性能测试过程
性能测试的方法
- 范围和非功能需求捕捉:通常需要几天。
- 性能测试环境准备
- user case脚本化:一个user case通常需要半天。
- 创建和验证性能测试场景。1-2天。前提是创建了精确的负载模型,定义每个性能测试的结构和内容。
- 执行性能测试。通常需要5天左右。如果频繁重测,耗时更多。
- 收集数据和卸载软件。通常需要1天左右。
- 最后分析和报告。通常需要2-3天左右。
非功能需求分析
先决条件如下:
- 性能测试的截止期限
- 内部或外部资源OK。
- 测试环境的设计。尽量接近真实环境。
- 代码冻结。
- 专有的测试环境,
- 目标。
- 关键用例。识别、记录并准备脚本。
- 用例中的检查点。
- 选择的use case的输入、目标和会话数据。同时还需要考虑数据安全。
- 负载模型OK。
- 性能测试场景的数量、类型、use-case内容和虚拟用户的部署已经确定。还可能需要考虑时间,步长,注入细节等。
- 识别和记录应用、服务器和网络的KPI。注意需要关注基础设施。
- 性能测试的输出。
- bug提交方式。涉及测试团队成员和报告结构。工具、资源、技术和授权。另外还有培训,在外包的时候尤其重要。常见的架构如下:
基于上述信息,可以输出:
1.制定包括资源,时间线和里程碑的高层计划
2.包括所有的依赖、相关时间线、详细的场景和use case,负荷模型和环境信息的性能测试计划。
3.风险评估。
另外还需要注意迭代。
性能测试环境准备
步骤如下:
1.足够的时间来采购设备,配置和构建环境。
2.考所有部署模型要在LAN和WAN环境实验。
3.考虑外部链接。
4.提供足够的负荷注入容量。比如云主机。
5.确保应用正确部署到测试环境。
6.软件授权。
7.部署和配置性能测试工具。
8.部署和配置KPI监控。
Use-Case脚本
针对每个user case:
?确定会话数据的要求。其中一些可能来自概念验证(POC)。
?确认并应用输入数据的要求。
?检查点。
?修改脚本
?脚本单用户和多用户都可以执行。
性能测试场景构建
? 测试类型是什么(pipe-clean, volume, soak, or stress?),通常是针对user case进行单个用户(pipe-clean)测试,产生基线数据。然后加大并发和吞吐量。之后进行混合user case的容量测试。然后可能有soak和stress测试,最后还可能结合负载均衡和容灾等测试。
?思考时间和步长(尤其是压力测试)。
?负载注射器和虚拟用户的数量。
?注入方式:Big Bang, ramp-up, ramp-up/ramp-down with step, or delayed start。注意这几种方式可能是连接的。比如下图:
?测试执行控制:执行一段时间段、到达一定界限或测试数据耗尽停止或是用户介入。
?是否需要IP欺骗?
?您是否需要模拟不同的波特率?
?监控需求。
?Web的性能测试需要考虑浏览器缓存。还需要考虑新用户,活跃用户,回归用户等。
?技术影响,比如SAP比较消耗资源。
性能测试执行
1.pipe-clean测试。
2.容量测试。
3.隔离测试
4.压力测试。
5.浸泡测试,发现内存泄漏等问题
6.其他测试,比如负载均衡,容灾等。
性能测试分析和报告
?进行最后的数据收集(可能有软件卸载)。数据要有备份。
?比较试验结果与目标,决定是否通过。
?测试报告。