zoukankan      html  css  js  c++  java
  • 性能、负载、压力测试——从性能测试角度理解系统开发

    引言

    最近,由于旧机器下线,我对过去部署的一些服务做了迁移,顺带对新部署的服务做了一个简单的性能测试。在实施过程中,我发现自己对很多性能指标的理解很不清晰,对于并发数压力吞吐量延迟等概念,通常是以望文生义的方式使用。对于系统应该关注什么样的性能指标,认识也不完整。为此,我阅读了wiki百科以及一些博客,希望能对这方面的概念有一个较完整的认识。

    跑个题,最近重新提到了工程能力。这个词包含的范围很广,从技术路线选择、系统可维护性,到代码可读性、系统性能优化等,凡是能想到的有利于实现功能、提高效率的实践,似乎都可以被归为这个能力。然而,可以确定的是,工程能力的很大一部分体现,都与性能指标及其优化有关。如果在实现一个服务或系统时,对性能指标没有足够的关注,对性能相关的问题没有胸有成竹的回答,则很难说是有足够的工程能力。

    本文的主要内容是对性能测试做了简要总结。通过阅读维基百科及一些博客,了解性能测试的内容、指标、方法、目标。对这些文章做了一些摘要、总结、翻译。

    本文分为以下几部分:第二部分,是性能测试的分类,主要内容来自维基百科;第三部分,是如何实施性能测试,主要注意哪些问题,以及优化的方向,内容来自维基百科以及Grig Gheorghiu的两篇博客;第四部分,是如何区分性能测试、负载测试、压力测试,内容主要来自Grig Gheorghiu的两篇博客。

    性能测试分类

    在维基百科上性能测试的定义是

    In software engineering, performance testing is in general, a testing practice performed to determine how a system performs in terms of responsiveness and stability under a particular workload. It can also serve to investigate, measure, validate or verify other quality attributes of the system, such as scalability, reliability and resource usage.

    第一层含义是判断在一定工作负载下,系统响应能力稳定性。进一步延伸,包括测量、验证系统的其他质量属性,如可扩展性可靠性资源消耗

    性能测试可以包括但不限于以下类型:

    1. 负载测试(load testing)
      负载测试的目的,是为了解在预期的工作负载下,系统的行为。
    2. 压力测试(stress testing)
      压力测试是为了解系统提供服务能力的上限,了解系统在超出预期的压力下是否足够稳定。使我们了解如果当前负载增加至超出设计范围,系统是否能承受。
    3. 渗透测试(soak testing)
      渗透测试也叫忍耐力(endurance)测试,了解系统能否较长时间持续支撑的某个负载量,是否在持续的负载下会导致性能下降。
    4. 尖峰测试(spike testing)
      尖峰测试是突然增加或降低负载,看系统在负载量突然变化时的行为。
    5. 断点测试(breakpoint testing)
      断点测试与压力测试很相似,持续增加系统的负载,观察系统是否在预期的负载压力下出现性能下降或失败。
    6. 配置测试(configuration testing)
      观察修改系统配置,会对系统行为造成怎样的影响,例如负载均衡的配置。
    7. 隔离测试(isolate testing)
      隔离测试并非一个独立的测试项目,而是通过不断地重复某种测试,将出现问题的部分隔离出来。
    8. 互联网测试(internet testing)
      互联网测试通常是对全球性的服务来说的。测试负载的生成者,来自实际的目标用户所在地。

    上面的分类摘自维基百科。可以看出,不同类型测试有重叠甚至重复的部分,但每种测试又有其各自的目的。负载测试(load testing)和渗透测试(soak testing)可以同时进行。压力测试(stress testing)、尖峰测试(spike testing)和断点测试(breakpoint testing)似乎也可以同时进行,只要针对不同的目的做好对应的记录。如果出现问题,所有测试的目的最终都是将问题区域隔离出来(isolate testing)以进行优化。

    如何实施性能测试

    性能测试的目的和性能目标

    首先需要明确的一个问题是“why are we performance-testing?”。从目的来看,性能测试可以用来:

    • 验证系统达到预期的性能要求;
    • 对比两个系统,看哪个系统性能更好;
    • 找出系统的瓶颈以便优化

    不同的系统有不同的性能目标,但是通常都包含以下几个:

    1. 并发量。对于有用户登录状态的系统,同时服务的用户数通常是一个考量指标,因此并发量是一个重要性能目标。
    2. 吞吐量。对于无用户登录状态,吞吐量或者transaction rate是其关注的指标。
    3. 响应时间。从服务器端看,是从系统接收到请求,到系统发出反馈的时间。或者从客户端机器看,从客户端发出请求,到客户端收到响应的时间,压测脚本通常只能测到这个时间。服务器端的时间,需要通过日志等方式记录。

    性能规格

    性能测试之前应该有一个明确的性能规格说明,并且落地成文档。理想情况下,这个性能规格应该在需求阶段就制定下来,并且应该先于任何系统设计。

    性能规格通常应该至少回答以下问题:

    1. 性能测试的范围是什么?哪些子系统,哪些接口,哪些组件要被测试?要测试它们的哪些性能目标?
    2. 对于有用户接口的系统,用户并发量是多少?峰值和均值预期是多少?
    3. 目标系统是什么样子?包括系统环境、网络配置、硬件配置?
    4. 每个会话中各环节的负载比例是如何的?(登录20%,搜索40%,登出10%,选择30%)
    5. 系统中各会话的负载比例是如何的?(A回话20%,B会话40%,...)
    6. 后台批处理的时间要求什么?

    前提条件

    性能测试需要满足的条件包括:

    1. 系统稳定,或者待测的接口稳定。因为性能测试的目的不是发现bug,而是发现瓶颈。
    2. 目标明确。响应时间、并发、吞吐量?

    尽可能满足的条件是:

    1. 与系统使用真实环境保持一致

    性能测试应该尽可能早地开展,因为越早发现瓶颈,修复的代价越小。

    测试工具

    分为两部分:

    1. 一部分是用于模拟请求的performance scripting,包括HP LoadRunner, NeoLoad, Apache JMeter, Rational Performance Tester, Silk Performer和Gatling;
    2. 一部分是用于监控系统状态的monitor,包括系统本身的日志,以及监控CPU、内存、磁盘、网络的使用情况。

    实施与优化

    当目标、环境和工具已经就绪后,可以开始启动客户端模拟。对于一般的性能测试,目的是发现性能瓶颈,通常的做法是逐渐增加负载,记录并观察各项指标的变化。

    当发现系统的性能指标达不到预期时,以web服务为例,通常的优化思路是:

    1. 首先需要优化的是应用程序数据库。代码逻辑是否足够高效?数据库的查询是否高效?数据库是否针对常用查询语句做了优化?可以用的工具有jUnitPerf和pyUnitPerf。

    如果上述方案还无法满足,可以考虑以下思路:

    1. 增加Cache是否能提升效率;
    2. 对常用页面静态化;
    3. 考虑使用负载均衡,对系统进行横向扩展;
    4. 将服务划分为只读/读写;
    5. 提升机器的硬件性能,SSD、CPU、内存等;
    6. 提升网络带宽。

    性能、负载、压力测试的区别

    这一步分的内容完全来自于Grig Gheorghiu的博客,可以在原文看到更详细的解释。

    性能测试(performance testing)、负载测试(load testing)、压力测试(stress testing)三个概念经常被替换着使用,因为他们在实施方式上有相同的地方,但他们也确实有一些区别。在本文第一部分性能测试分类中,已经大致介绍了概念上的区别,主要体现在目的不同。

    1. 性能测试。目的是发现系统瓶颈,并为系统设定一个性能baseline,以便为后续的优化设定一个参照。通常是白盒测试。
    2. 负载测试。目的是确认系统是否满足某负载要求,以及发现在高负载下是否会出现低负载无法出现的bug。通常是黑盒测试。
    3. 压力测试。目的是看系统在异常环境,如压力过大、网络断开、磁盘故障、资源不足等情况下的表现,检查系统的稳定性、对异常的恢复能力。

    其实只要测试的目标明确,具体使用哪个名字并无太大关系。

  • 相关阅读:
    GIT分支的一些开发心得
    java文件压缩和解压
    java发送邮件
    单例多例
    String,StringBuffer,StringBuilder区别
    GIT文件的三种状态
    javascript 常用技巧
    javascript优化工具 Doloto
    thinkphp 5内置验证规则-基本版
    php+redis配置
  • 原文地址:https://www.cnblogs.com/terencezhou/p/9988672.html
Copyright © 2011-2022 走看看