vlambda博客
学习文章列表

性能测试之服务器性能测试工具及实战

本文发表于《程序员》杂志 2013 年

👀

   

1,服务器性能测试工具简介

服务器性能测试主要是以测试服务器的性能为主的测试方法,通过模拟多用户按照预定义好的规则对服务器进行并行访问,监测并记录服务器的 Response Time,Throughput, Server Hits 以及 Memory 和 CPU 等实时数据,通过分析测试数据,得到服务器的各项性能指标从而发现服务器的性能瓶颈和内存泄漏等问题。进行这样测试的工具称之为服务器性能测试工具。

服务器性能测试工具通过多年的发展,已经从 ab/abs 这种简单的命令行工具发展到有丰富 UI 配置界面的 Jmeter,LoadRunner,到现在的 Gatling 支持 DSL/Actor, LoadUI 支持图形化网络接口的新一代工具, 可以说是种类繁多。对于各种不同的需求,应该都能找到一款相对合适的工具。如果只是想做入门级别的压力测试,比如只是需要简单的产生许多 HTTP 请求,那么 ab 和 curl-loader 就能完成工作;如果需要在有限的设备上进行最大强度的发包,那么 Gatling 和 Locust 将是不二选择;如果资金充裕,商用的 LoadRunner 和 LoadUI Pro 绝对能满足需求;如果你是 Windows 的忠实拥护者,那么 OpenSTA 和 WebLoad 也是很好的选择;如果你并不是喜欢编程和修改 xml,并且资金也不充裕,那么 Jmeter 和 LoadUI 是不错的选项;如果你是 Python 爱好者,那么 Locust 和 Grinder 将可以延续你的爱好。

总之,每个工具都有自己的优点和缺点,只要根据需求以及资金情况选择合适的工具就可以了。因为每个工具的基本功能都是产生尽可能多的网络请求,然后收集各种数据并展现出来。只不过由于使用的技术不同以及开发者的目标不同,所以得到的效果不一样而已(详见第二节 )。

👀

   

2,主要的服务器性能测试工具

对于现在已有的服务器性能测试工具如果按照表现模式,主要可以分为命令模式,图形模式,脚本模式。下面就对一些主要的工具进行一下介绍。

命令模式:

  • ab/abs:ab/abs 是 Apache Http Server 自带的一款的性能测试工具,安装了 Apache 就可以在其目录下面找到它。它具有体积小,性能高的特点,缺点是没有界面,报表简单,很难使用其进行复杂流程的性能测试,必须借助第三方语言的帮助,比如 Bash Shell,Python 等。

  • curl-loader:curl-loader 是一款基于 c 开发的命令行工具,拥有和 ab/abs 一样的特点,但是支持更多的功能,比如 FTP 和 TLS/SSL 协议栈,支持用户认证和登陆,拥有更好的报表系统。所以如果想要一个功能加强版的 ab/abs,那就选择 curl-loader。

图形模式:

  • LoadUI:LoadUI 是一款开源免费的性能测试工具。它除了拥有和其他性能测试工具一样的功能以外,还具有一个很有创意的特性:图形化网络接口,即拖即放即使用。这个特性使得可以通过拖放网络接口组件来组成的网络拓扑图,然后基于这个拓扑图进行性能测试,以及检查和观察测试情况。它基本上支持所有标准协议,比如 HTTP(S), HTML, SOAP/WSDL 和 REST to AMF, JDBC, and POX。作为入门级别的测试工具或者练习,它绝对是一款很不错的工具。

  • LoadUI Pro:LoadUI Pro 是基于 LoadUI 增强功能的收费版,其更为强大的功能绝对物超所值,详细比较请见(http://www.loadui.org/About-loadUI/compare-loadui-and-loadui-pro.html)。虽然 LoadUI 价格也不便宜,但是和 LoadRunner 比就便宜很多了 (http://www.loadui.org/About-loadUI/compare-loadui-and-loadui-pro.html)。虽然 LoadUI 价格也不便宜,但是和 LoadRunner 比就便宜很多了

  • LoadRunner:LoadRunner 可以算业界最出名,也是功能最为强大的服务器性能测试工具,当然价格也十分昂贵。它是 2006 年 HP 从 Mercury Interactive 购买过来的产品。它可以模拟各种性能测试行为,支持的协议也十分众多,比如 Flex AMF, Citrix ICA, Remote Desktop Protocol (RDP), ERP/CRM (e.g. SAP, Oracle eBusiness, Siebel and PeopleSoft), Databases, Mail Clients, Web Services 等。如果资金充裕,选择它应该能满足绝大部分需求,不过其性价比确实是一个不大不小的问题。

  • Apache Jmeter:Apache Jmeter 是现在最流行的免费服务器性能测试工具之一。它是一个 100%纯 java 开发的应用程序,其图形界面的易用性可以和 LoadRunner 相提并论,其丰富的插件提供了各种协议的支持,丰富的测试报表,扩展组件 BSF 支持各种语言的扩展,比如 JavaScrip,Ruby,Python 等,以及支持分布式等各种先进的特性。当然 Jmeter 也不是完美的,它也存在一些不足。不过对于服务器性能测试入门以及没有很好的技术储备并且资金不充裕的公司来讲,Jmeter 将是一个完美的选择。

脚本模式:

  • Tsung:Tsung 是一款基于 Erlang 开发的高性能免费的服务器性能测试工具,它具有分布式,录制脚本,图形报表系统等功能,协议方面支持 HTTP,SOAP,和 Jabber Server(SSL)等。其测试脚本是通过 XML 来进行描述的。由于没有图形管理界面,所以编写和维护测试脚本将会是一个不小的困难。如果要对其进行扩展,也需要通过 Erlang。除非公司有 Erlang 的技术人员,不然就不要轻易选择其作为主要的测试工具。

  • Grinder:Grinder 是一个基于 Java 开发,通过 Jython(最新版增加了 Clojure 的支持)驱动的 Load-Testing 框架。由于可以通过编写 Jython 脚本来实现测试案例,从而获得了一些喜欢 Python 的技术人员的喜爱。不过由于 Jython 本身的一些问题,也造成了 Grinder 会出现内存泄漏,不稳定等情况。所以对于小规模性能测试并且拥有很好的 Python 技术人员储备的公司,还是可以选择 Grinder 进行尝试。

  • Locust: Locust 是一个基于 Python 开发,并且通过编写 ython 脚本来实现测试场景。它通过异步事件模型达可以实现高并发请求,同时它还支持分布式模型,从而可以扩展并实现超高并发请求。如果性能有很高的要求,并且拥有很好的 Python 技术人员,可以选择 Locust 进行性能测试。

  • Gatling:Gatling 是最近才出现的新一代服务器性能测试工具,它具有高性能,轻量表报,以及 DSL 脚本的特性。如果想要获得和 Tsung 一样或者更好的性能,如果希望支持简单易读的 DSL 脚本并且希望能在 IntelliJ 有插件的支持,如果想要轻量报表系统,那么 Gatling 是唯一选择。

如果资金充裕, 购买商用的测试工具是很好的选择,但是如果只是一个创业公司或者并不想在服务器性能测试工具上做太多的投资,那么第三节的内容也许能提供一些帮助。

👀

   

3,三个真实项目中性能测试工具实战


   

1, 在一个 Erlang 开发的电信计费系统中从 Tsung 转向 Jmeter

我曾参加过一个电信计费系统项目的测试工作,这个项目始于 90 年代,那个时候 Java 刚刚起步,对于并发性能和容错要求十分严格的电信系统来讲,Erlang 几乎是唯一选择。但是由于公司规模较小,所以也没有太多的预算去购买商用的性能测试工具, 所以只是简单的将单元测试改装一下进行并发调用(比如调用一个函数 1 万次)来做性能测试。这样的目的仅仅只是检查函数被并发调用的时候会不会出现一些问题,而无法测试真实的场景。进行到项目中期的时候,我们发现这样的测试其实并不能发现一些场景中的性能问题,所以开始寻找一个工具可以基于场景非单元而进行性能测试。由于项目的开发人员都十分熟悉 Erlang,也是基于 Erlang 优秀的并发性,所以选择了用 Erlang 开发的 Tsung。虽然 Tsung 支持录制功能,由于它的测试脚步都是基于 XML,修改也需要直接修改 XML,所以在使用过程中发现对于流程比较复杂的测试案例,并且流程需要变化的时候对测试脚本的开发和维护十分麻烦。在 Debug 测试脚本的时候无法动态显示报表而只能看日志,所以最终我们决定抛弃 Tsung 而使用 Jmeter。

选用 Jmeter 主要是基于其开发和维护的大部分工作只需要在界面上对 Test Plan 进行配置,然后可以通过 BSF 进行少量的脚本开发就能开发复杂的测试案例。我们的具体开发流程是首先通过界面配置并发线程的规则以及主要的测试流程,然后对于某些有特殊要求的测试案例编写 Ruby 脚本并封装在 BSF Sampler 中,比如对结果进行特定分析,处理然后存储到数据库或者文件等特殊需求。由于 BSF 支持几乎所有可以在 JVM 上运行的语言,比如 Jython,JRuby,Javascript 等,所以可以选择熟悉的语言编写这种特殊需求的测试扩展。

当然 Jmeter 也不是完美的,因为使用过程中我们也遇到一些问题:

  • 通过界面方式运行 Test Plan 的时候,如果线程过多,比如超过 1000-2000 个线程(在我们项目特定的硬件环境下),那么界面以及 Listener 里面的图表会出现死屏的情况。所以开发和调试的时候需要把线程设置到 1000 以下最好,或者通过命令行无界面的方式进行测试。

  • 由于 Jmeter 是基于 Java Thread 的模型开发的,并没有 Tsung 这种基于 Actor 模型的效率高,所以我们选用了 Cluster 的模型进行测试。但是发现当 Node 过多,从 Node 传向 Server 的数据也会跟 Node 的个数成线性增长,但是能达到的并发请求却不能成等比线性增长,要低于理论值很多,所以对硬件资源的浪费也是比较大的。

  • 如果设置的线程太多,很容易出现 OOM,所以我们一般最高单机设置不会超过 2000 个 Thread 对于简单的测试案例。

  • 如果进行 Soak Testing 超过 1 天,并且 Result 采用 XML 的格式存储,其结果文件大小会达到几个 G 甚至 10 多个 G。如果 Result 改为 CSV 格式存储,其大小也有几百兆,如果 Testing 超过 1 周,那么数据也是巨大的。打开这个巨大的 Result 文件查看各种 Listener 图表需要很长时间,是一件十分痛苦的事情,如果太大还会出现 OOM。


   

2, 在一个 J2EE 开发的 Social Network 项目中从 Grinder 转向 Jmeter

21 世纪开始的 10 年是属于社交网络的 10 年,全世界的社交网络如雨后春笋般一下子都涌现出来。我们公司也是其中一笋,开发了一款社交网络系统。对于社交网络系统,其并发性能和容错的要求一点也不亚于电信计费系统。由于开发此系统的时候正是脚本开发时代,所以系统的架构师选择了基于 Python 开发的 Grinder 来做性能测试。由于 Grinder 需要编写 Jython 脚本,并且由于项目开发进度的问题,只是开发了基本场景的 Performance Testing, Load Testing,Soak Testing。基于这些场景我们开始寻找系统的处理极限,是否存在内存泄漏等问题,根本没有时间去做比较复杂测试 。在做 Soak Testing 的时候我们还证实了 Grinder 存在的内存泄漏问题,最终这一切不得不使我们抛弃了 Grinder 而选择 Jmeter。

在这个项目里面我们尝试了去通过将 Server 部署在 VM Node 上,从而使其在低配置的硬件设备上运行。这样通过 Jmeter 就不需要产生大规模的并发请求,就可以比较容易的达到 Server 的访问极限,从而规避 Jmeter 的性能问题。当然这种方法并不是一种完美的解决方案,也存在其问题,比如无法真实模拟现实情况。但是由于部署和产品环境一样的硬件进行测试,本身硬件成本就十分的高。利用这种方案,不仅减少了公司对测试环境的硬件投入,还减少了一定软件成本,比如配置和维护 Jmeter Cluster。最后通过 CI 进行测试时候,也减少了 CI 的配置和维护成本。


   

3, 在一个开发的 J2EE 的商业系统中尝试使用新一代工具 Gatling

最近正在开发一个基于 J2EE 的商业系统,其业务逻辑比较复杂, 但是对并发性能要求并不十分高,所以从项目开始就选择了 Jmeter 作为服务器性能测试工具。我们基于 Jmeter 开发了各个场景下的 Test Plan,并通过 Jenkins 进行测试。由于测试场景比较复杂,所以 Test Plan 里面的 Sampler, Assertion 等也很多,运行时占用的内存也比较多,数据交互也比较多,存储的 Result 也比较大。鉴于我们之前项目的经验,Jmeter 并不适合做这样项目的 Soak Testing。

幸运的是 Gatling 的出现刚好能解决这样的问题。Gatling 是基于 Scala 和 Akka 开发的新一代服务器性能测试工具,它使用的 Actor 和异步 IO 使其在并发性能方面远远超越了 Jmeter,它的报表系统是 HTML 文件来存储的并配有丰富的动态图表,所以它的高性能和轻量报表系统刚好弥补了 Jmeter 在 Soak Testing 和单机高性能方面不足的问题。

Gatling 还具有以下特性:

  • 支持 DSL,使得测试脚本更为简明和更好的可读性

  • 支持轻量和动态页面的 HTML 测试报表

  • 支持录制并直接生成测试脚本

  • 支持 Maven 插件,可以很好的和 Eclipse/IntelliJ 等 IDE 进行集成

  • 支持 Jenkins 插件

  • 支持 Debian Package,所以带 Debian 和 Ubuntu 下面可以通过 apt-get 进行快速安装和使用

现在我已经开始考虑尝试用 Gatling 重写一部分测试案例来进行 Soak Testing,从而将项目带入 Gatling 时代。

Gatling 也不是完美的,它发布的时间也不长,当然也存在一些不足,详见下节。

👀

   

4,服务器性能测试工具的发展和设想

虽然现在已有的各种免费服务器性能测试工具已经拥有了十分丰富的功能,但是仍有一些需要改进和加强的地方。

更为强大的 Server Monitor: 虽然 Jmeter 的 Plugin 已经实现了 Server Monitor,或者也可以通过第三方工具比如 OpenTSDB 进行 Server Monitor,但是真正使用起来还是很不方便。比如在第二个实战项目中,我们就是自己通过 Python 脚本收集 Server 的 JMX 信息,然后传递给 OpenTSDB,分析数据的时候需要根据时间轴分别查看 Jmeter 和 OpenTSDB 的图表。如果能把收集和显示 JMX 等这类 Server 系统内部信息的功能集成入测试工具,那么就可以在同一个报表系统里面查看 Client 端和 Server 系统内部各种信息,从而更简单的进行测试数据分析。

更好的 CI 支持:现在最流行的免费 CI-Jenkins/Hudson 虽然有插件支持 Jmeter 等工具,但是仅仅是显示一下汇总数据,并不能将各种报表和详细数据显示到 CI 上。如果 CI 上能直接显示甚至自定义各种数据报表以及实时显示数据报表,那么将可以极大的方便的日常测试工作,并加快测试分析和测试数据汇总。

Jmeter 的未来:Jmeter 对于不会写代码的测试人员就是一个天使,但是由于其性能和报表问题,往往不能在有限的设备上发挥硬件的最大能力。所以如果能用 Actor 替换掉 Thread,让其能充分发挥硬件的性能,并且能有轻量级的报表系统,比如直接可以将 Report 存储成为 HTML 文件,那么 Jmeter 将会迎来另外一个春天。

Gatling 的未来:Gatling 是最新一代服务器性能测试工具,它不仅有出色的性能,而且而且还支持 DSL 和 Scala 脚本开发(Scala 可以不需要编译而以脚本的方式执行)。但是它现在不支持分布式也算是它的一个不大不小的问题,所以如果未来 Gatling 支持分布式并支持更多种类的报表和协议,那么它很有可能在未来的免费服务器性能测试工具市场上占据主导地位。

总的说来,现在已有的服务器性能测试工具基本上都能满足基本的业务需求,只不过根据自己的技术能力和业务需己选择适合自己的就可以了。最后还是给出我个人的推荐,对于 HTTP 服务器:免费-Gatling, Locust;收费-LoadUI Pro。