可不可不要这么样徘徊在目光内 / 你会察觉到我根本寂寞难耐 / 即使千多百个深夜曾在梦境内 / 我有吻过你这毕竟并没存在 / 人声车声开始消和逝 / 无声挣扎有个情感奴隶 / 是我多么的想她 / 但我偏偏只得无尽叹谓 / 其实每次见你我也着迷 / 无奈你我各有角色范围 / 就算在寂寞梦内超出好友关系 / 唯在暗里爱你暗里着迷 / 无谓要你惹上各种问题 / 共我道别吧别让空虚使我越轨 /

发布新日志

  • https vs http 性能

    2007-12-26 15:58:06

    最近比较忙,blog 也更新的有点慢

    今天谈谈 https 的性能问题,个人见解。

    今天去看微软的一些recorded 的webcast,没有想到livemeeting 的webserver 竟然都是全部https的。用户的登陆验证过程还可以理解,没有想到所有的文件资源居然也是通过https去访问,这个其实就做的过于安全了。一个20M的流文件,光服务端加密估计就要消耗很多cpu和能源了,不过微软的服务器够power。跟着俺的客户端也要解密这一部分,其实也消耗了俺的资源,hoho。总结一下,我觉得https 不应该用到不该用的地方。

     

    1.       HTTPS 一定要有明确的选择理由.

    a)         HTTPS 实际上是SSL用于HTTP.

    b)        主要解决了两部分的问题.

                             i.              1. 信任主机的问题. 采用https server 必须从CA 申请一个用于证明服务器用途类型的证书. 改证书只有用于对应的server 的时候,客户度才信任次主机. 所以目前所有的银行系统网站,关键部分应用都是https . 客户通过信任该证书,从而信任了该主机. 其实这样做效率很低,但是银行更侧重安全. 这一点对我们没有任何意义,我们的server ,采用的证书不管自己issue 还是从公众的地方issue, 客户端都是自己人,所以我们也就肯定信任该server.

                           ii.              2. 通讯过程中的数据的泄密和被窜改. 这里有两个层次

    1.         一般意义上的https, 就是 server 有一个证书.

    a)         主要目的是保证server 就是他声称的server. 这个跟低一点一样.

    b)        服务端和客户端中件的所有通讯,都是加密的.

                                                                     i.              具体讲,是客户端产生一个对称的密钥,通过server 的证书来交换密钥. 一般意义上的握手过程.

                                                                     ii.              加下来所有的信息往来就都是加密的. 第三方即使截获,也没有任何意义.因为他没有密钥. 当然窜改也就没有什么意义了.

    2.         少许对客户端有要求的情况下,会要求客户端也必须有一个证书.

    a)         这里客户端证书,其实就类似表示个人信息的时候,除了用户名/密码, 还有一个CA 认证过的身份. 应为个人证书一般来说上别人无法模拟的,所有这样能够更深的确认自己的身份.

    b)        目前少数个人银行的专业版是这种做法,具体证书可能是拿U盘作为一个备份的载体.

    2.       HTTPS 一定是expensive.

    a)         本来简单的http协议,一个 get 一个response. 由于https 要还密钥和确认加密算法的需要.单握手就需要6/7 个往返.

                             i.              任何应用中,过多的round trip 肯定影响性能.

    b)        接下来才是具体的http协议,每一次响应或者请求, 都要求客户端和服务端对会话的内容做加密/解密.

                             i.              尽管对称加密/解密效率比较高,可是仍然要消耗过多的CPU,为此有专门的SSL 芯片. 如果CPU 信能比较低的话,肯定会降低性能,从而不能serve 更多的请求.

                           ii.              加密后数据量的影响.

    1.         这个我用128bit RC2 测试了一下,加密后数量跟加密前基本相同.

    3.       HTTP VS HTTPS 的性能

    a)         这个由于很多人测试的背景不一样,由于时间太紧,我没有写出了一个类似 ACT 一样测试web https 的压力工具. 看了一下别人的观点.

    b)        有些人说https 的性能是 http 40 % , 有些人说可能80%.

    c)        我的观点.

                             i.              https 的关键性能影响是 CPU 和往返. 如果CPU 很强的话, 性能可能就是有人讲的80%. 如果cpu 是瓶颈的话, 有人讲原来可以server 330-500个请求每秒,现在只有30-50%

                           ii.              不需要用https 的地方,就尽量不要用.

    1.         考虑前面提到的权衡

                          iii.              微软在设计高性能的web 应用程序中这么讲:

    Segregate Secure and Non-Secure Content[1]

    When you design the folder structure of your Web site, clearly differentiate between the publicly accessible areas and restricted areas that require authenticated access and Secure Sockets Layer (SSL). Use separate subfolders beneath the virtual root folder of your application to hold restricted pages such as forms logon pages, checkout pages, and any other pages that users transmit sensitive information to that needs to be secured by using HTTPS. By doing so, you can use HTTPS for specific pages without incurring the SSL performance overhead across your entire site.

    Only Use SSL for Pages That Require It

    Using SSL is expensive. Only use SSL for pages that require it. This includes pages that contain or capture sensitive data, such as pages that accept credit card numbers and passwords. Use SSL only if the following conditions are true:

    ·                     You want to encrypt the page data.

    ·                     You want to guarantee that the server to which you send the data is the server that you expect.

    For pages where you must use SSL, follow these guidelines:

    ·                     Make the page size as small as possible.

    ·                     Avoid using graphics that have large file sizes. If you use graphics, use graphics that have smaller file sizes and resolution. Or, use graphics from a site that is not secure. However, when you use graphics from a site that is not secure, Web browsers display a dialog box that asks the user if the user wants to display the content from the site that is not secure.

  • (二)成功的 Web 应用系统性能测试

    2007-08-22 14:10:00

                    图一:在线用户数和响应时间时间的趋势图
                    

            针对基于吞吐量的性能测试需求,可通过下图的曲线来描述性能测试结果。以网上购物系统为例,下图描述下定单的并发用户、下定单响应时间以及吞吐量(服务器每秒处理定单笔数)之间的关系,从而快速判断系统是否能满足性能测试需求。从下图中可看出,并发用户增加,请求的响应时间也增加。服务器的吞吐量是先随并发用户数增加而增加,当吞吐量到达一定峰值后,再增加并发用户数,吞吐量会减少。原因在于当并发用户数少时,向Web服务器提交的请求量不大,服务器处理能力还有富余,所以吞吐量逐步增大;但当并发用户数超过某一值时,由于向服务器提交的请求太多,造成服务器阻塞,反而导致吞吐量减少。

                                  图二:响应时间、吞吐量和并发用户数的趋势图

                     

            3 如何获取合理的性能测试需求

            前一章介绍了Web应用系统的性能测试过程,确定性能测试需求是整个性能测试的起点和成功的重要因素。性能测试需求定义得过高,虽然确保系统上线后能满足性能需求,但可能会造成硬件资源的浪费;性能测试需求定义得过低,系统上线后可能会出现性能问题。如何通过分析系统上线后可能的用户访问行为,来获得合理的性能测试需求指标呢?

            假设现有一个基于Web的办公自动化系统(简称OA系统),该系统提供公文收发和查询功能。在部署该系统前,将对该系统进行性能测试。下面将详细介绍如何分析该OA系统的使用情况,定义合理的性能测试需求。

            3.1 如何获得OA系统的在线用户数量

            在线用户数量是指在特定时间区间内,有多少用户访问Web应用系统(对应到Web服务器的Session数),根据系统可能访问用户数以及每个用户访问系统的时间长短来确定。

            对于将要部署的OA系统,通过分析获得该系统有8000个注册用户,基本上所有的用户每天(8小时工作时间)都会访问OA系统,平均在线时间(从登录OA系统到退出OA系统之间的时间间隔,也可以是多次在线时间的合计)为12分钟,那么该OA系统的平均在线数(也就是Web应用Session变量数)为200个(8000 * 0.2 / 8),假设峰值在线用户数是平均在线用户数的3倍(该倍数可根据实际情况调整),则性能测试需求的在线用户数为600。
        3.2 如何确定OA系统的性能测试用例 
            由于时间和资源限制,不可能对Web应用系统的所有功能进行性能测试,而是从业务的角度(如某一功能操作的用户多)和技术的角度(如某一功能虽然访问用户不多,但内部处理逻辑复杂或处理数据量大)来选择Web应用系统的特定功能作为性能测试用例。

            以OA系统为例,由于所有用户都经常公文查询功能,因此确定的性能测试用例为公文查询。

            3.3 如何确定OA系统的响应时间

            响应时间的快慢直接影响了系统使用用户的满意度,采用平均响应时间来描述系统系统性能测试需求是不科学的,因为无法直接和客户的满意度挂钩。而且,在做性能测试,如果某一请求的响应时间过长或过短,将导致平均响应时间和实际情况偏离。

            以OA系统为例,定义的响应时间需求为:90%(该百分比和要求的系统用户满意度相关)的查询请求响应时间不超过8秒(该时间可根据实际情况确定)。

            3.4 如何确定OA系统的交易吞吐量

            单位时间内Web应用系统需处理多少笔特定的交易可通过统计获得。以OA系统为例,假设每个用户每天(一天按8小时计算)平均会查询公文4次,那OA应用的Web服务器平均每分钟要能处理8000 * 4 / ( 60 * 8 ) = 66.67笔查询公文交易,考虑到峰值因素,要求每分钟能处理66.7 * 3=200笔查询公文交易。

            3.5 OA系统性能测试需求描述

            通过前面的分析,能明确定义合理的性能测试需求。OA系统性能测试需求定义如下:

            基于在线用户数的性能测试需求:600个在线用户按正常操作速度访问OA系统的查询公文功能,所有查询请求的成功率是100%,而且90%的查询请求响应时间不大于8秒。

            基于吞吐量的性能测试需求:OA系统在每分钟内需处理200笔查询公文操作,交易成功率为100%,而且90%的请求响应时间不大于8秒。

            4 总结

            Web应用性能测试项目成功的关键不在于性能测试工具,而在于有效的性能测试分析方法和实践。只有切实掌握性能测试需求分析方法,性能测试实践经验,才能保证一个Web应用性能测试的成功。

  • (一)成功的 Web 应用系统性能测试

    2007-08-22 14:08:35

        性能测试是 Web 应用系统的一项重要质量保证措施。在现实中,很多 Web 性能测试项目由于性能测试需求定义不合理或不明确,导致性能测试项目不能达到预期目标或进度超期。本文针对 Web 应用系统的技术架构和系统使用特点,探讨如何有效实施性能测试过程,并重点介绍如何分析获得合理的性能测试需求,最终对 Web 应用系统性能进行科学、准确的评估。

        1 引言

            基于Web服务器的应用系统由于提供浏览器界面而无须安装,大大降低了系统部署和升级成本,得以普遍应用。目前,很多企业的核心业务系统均是Web应用,但当Web应用的数据量和访问用户量日益增加,系统不得不面临性能和可靠性方面的挑战。因此,无论是Web应用系统的开发商或最终用户,都要求在上线前对系统进行性能,科学评价系统的性能,从而降低系统上线后的性能风险。

            在很多性能测试项目中,由于不能合理定义系统的性能测试需求,不能建立和真实环境相符的负载模型,不能科学分析性能测试结果,导致性能测试项目持续时间很长或不能真正评价系统性能并提出性能改进措施。

            本文在总结许多Web应用系统性能测试实践经验和教训的基础上,从与性能测试工具无关的角度介绍Web应用系统性能测试的方法和实施过程,以及如何定义合理的性能测试需求。

        1.1 术语定义

            性能测试:通过模拟大量浏览器客户端同时访问Web服务器,获得系统的性能数据。

            虚拟用户:模拟浏览器向Web服务器发送请求并接收响应的一个进程或线程。

            响应时间:浏览器向Web服务器提交一个请求到收到响应之间的间隔时间。

            思考时间:浏览器在收到响应后到提交下一个请求之间的间隔时间。

            请求成功率:Web服务器正确处理的请求数量和接收到的请求数量的比。

            吞吐量:单位时间内Web服务器成功处理的HTTP页面或HTTP请求数量。

            在线用户:用户通过浏览器访问登录Web应用系统后,并不退出该应用系统。通常一个Web应用服务器的在线用户对应Web应用服务器的一个Session。

            并发用户数:Web服务器在一段时间内为处理浏览器请求而建立的HTTP连接数或生成的处理线程数。当所有在线用户发送HTTP请求的思考时间为零时,Web服务器的并发用户数等于在线用户数。

       1.2 Web应用系统技术架构

            Web应用系统的前端为浏览器,后台为Web服务器(如Apache,Microsoft Internet Information Server),浏览器和Web服务器之间的交互基于HTTP协议。HTTP协议本身是无连接的,Web服务器通过Session机制来建立一个浏览器所发出的先后连接之间的关联。通过实验证明,当浏览器客户端在首次访问Web服务器后,如果该浏览器客户端不发送后续请求,服务器维持该浏览器客户端的Session变量所消耗的系统资源非常小。

            2 Web应用系统性能测试过程

            标准的Web应用系统性能测试过程包括确定性能测试需求,开发性能测试脚本,定义性能测试负载模型,执行性能测试和形成性能测试报告。本章将分别介绍上述过程,并通过举例说明如何完成每一环节。

            2.1 确定性能测试需求

            科学定义Web应用系统性能测试需求对一个成功的性能测试非常重要。通常,Web应用系统的性能测试需求有如下两种描述方法。

            2.1.1 基于在线用户的性能测试需求

            该需求描述方法主要基于Web应用系统的在线用户和响应时间来度量系统性能。当Web应用系统在上线后所支持的在线用户数以及操作习惯(包括操作和请求之间的延迟)很容易获得,如企业的内部应用系统, 通常采用基于在线用户的方式来描述性能测试需求。以提供网上购物的Web应用系统为例,基于在线用户的性能测试需求可描述为:10个在线用户按正常操作速度访问网上购物系统的下定单功能,下定单交易的成功率是100%,而且90%的下定单请求响应时间不大于8秒;当90%的请求响应时间不大于用户的最大容忍时间20秒时,系统能支持50个在线用户。

            2.1.2 基于吞吐量的性能测试需求

            该需求描述方法主要基于Web应用系统的吞吐量和响应时间来度量系统性能。当Web应用在上线后所支持的在线用户无法确定,如基于Internet的网上购物系统,可通过每天下定单的业务量直接计算其吞吐量,从而采取基于吞吐量的方式来描述性能测试需求。以网上购物系统为例,基于吞吐量的性能测试需求可描述为:网上购物系统在每分钟内需处理10笔下定单操作,交易成功率为100%,而且90%的请求响应时间不大于8秒。

            2.2 开发性能测试脚本

            在确定Web应用系统性能测试需求后,就要根据性能测试需求中确定的功能开发性能测试脚本。比如,针对前面定义的网上购物系统的性能测试需求,将开发下定单功能的性能测试脚本。

            性能测试脚本是描述单个浏览器向Web服务器发送的HTTP请求序列。每个性能测试工具(如IBM  Rational Performance Tester, LoadRunner)所提供的测试脚本语法是不同的。测试人员利用性能测试工具可从头手工编写测试脚本,也可以通过录制浏览器和Web服务器之间的网络通信数据而自动形成测试脚本。

            任何性能测试工具都不能保证录制形成的性能测试脚本的正确性,测试人员应通过在单用户下运行性能测试脚本对其正确性进行验证。测试脚本不正确的一个重要原因就是脚本的数据关联不正确,也就是并没完全建立一个测试请求和前面的响应内容之间的关联。测试脚本HTTP请求和响应之间的数据关联是否正确的一个重要标准是单用户运行脚本,脚本能完成期望的功能。

            在完成性能测试脚本的数据关联后,需要对脚本进行参数化,也就是把脚本中的某些请求数据替换成变量,变量的值来于一个独立的数据文件,从而保证在多虚拟用户运行脚本的情况下,每个虚拟用户所提交的数据是不同的。

            此外,为了测试Web应用的可靠性,还需要对请求所收到的响应进行验证(比如验证响应的HTTP返回码或验证响应的内容),便于性能测试完成后统计请求成功率。

    2.3 建立性能测试负载模型

            性能测试负载模型定义了测试工具如何向Web应用系统提交请求,包括向Web应用系统发送请求的虚拟用户数,每个虚拟用户发送请求的速度和频率。针对前面介绍的网上购物系统的性能测试需求,在性能测试工具中定义的性能测试负载模型应包括如下信息:

            虚拟用户数:性能测试不仅仅是执行一次,而且每次执行时虚拟用户数也不固定,因此在性能测试负载模型中定义的虚拟用户数将在测试执行时进行设置。

            虚拟用户发送请求的思考时间和迭代次数:虚拟用户发送请求的思考时间长短是决定Web应用系统负载量的重要因素之一,而迭代次数将决定性能测试的执行持续时间。对基于在线用户的性能测试需求,将基于录制脚本时记录的思考时间,而且由于现实中不同用户访问系统的思考时间不同,可把思考时间设置为在一定范围内的随机值。对于基于吞吐量的性能测试需求,将把思考时间设置为零,此时Web应用系统的在线用户数量将等于并发用户数。同时,为了避免性能测试压力的随机性,将增加请求的迭代次数来增加测试执行持续时间,从而获得系统在稳定压力下的性能数据。

            虚拟用户启动模式:在现实中,Web应用系统的用户不太可能同时做相同的操作,因此为了让Web应用系统所承担的压力随时间均匀分布,建议虚拟用户依次启动,同时也避免大量用户同时登录造成系统阻塞。以10个虚拟用户模拟下定单为例,可设置每个虚拟用户间隔30秒启动,这样10个虚拟用户可在5分钟后完成启动,并保证10个虚拟用户不会在同一时刻下定单,从而更符合实际情况。

            2.4 执行性能测试

            执行性能测试是指通过多次运行性能测试负载模型,获得系统的性能数据。在执行过程中,需利用测试工具、操作系统、系统软件(如Web Server或DB Server)提供的资源监控手段对资源进行监控和分析,帮助发现资源瓶颈,并在系统层面进行优化。同时,还需对应用进行性能分析,帮助定位应用代码中的性能问题,切实解决系统的性能问题。

            2.5 形成性能测试报告

            性能测试项目的最后阶段就是向相关人员提交性能测试报告,汇报性能测试结果。在向相关人员汇报性能测试结果时,并不是性能测试报告越丰富、性能数据越多越好。好的性能测试报告是能准确、简单地传递性能测试结论,而不需太多的技术细节。

            针对基于在线用户数的性能测试需求,可通过下图总结性能测试结论。其中横轴是在线用户数,纵轴是响应时间,如40在线用户访问网上购物系统时,90%的下定单请求响应时间不超过10秒。

  • 性能测试的门槛

    2007-08-22 14:07:07

       随着软件测试行业的逐渐发展,性能测试也变得火热起来。从各大测试论坛和测试交流群的交流主题的热门程度来看,性能测试已经成为大家非常感兴趣的话题。性能测试作为软件测试行业技术性相对较高的工作自动化测试、白盒测试、性能测试)来说,个人觉得其操作门槛还是不低的。对于测试新手来说入门有一定的难度,做的好就更加不容易了,可能花了不少时间而实际收获不大。因此觉得有必要来专门探讨一下性能测试的门槛,以及如何更好的迈进这个门槛。

            先来分析一下一些关于性能测试入门级的常见问题:

    1、请问怎么做象PhotoShop这类单机程序的性能测试;

    2、用Delphi开发的程序,应该用什么协议来录制脚本;

    3、用IP欺骗能对外网进行测试吗;

            关于第1个问题,问题本身并没有错误,单机版也有性能问题。但和我们通常所说的性能测试是两回事,不能混为一谈。如果这个算是问题的话,那我想是由于不清楚性能测试的概念和原理所造成的。第2个问题也不少见,但这种问题无法回答。我们知道,性能测试采用的协议是由被测系统的体系架构和通信协议决定的,而不在乎你用什么开发工具或开发语言。第3个问题,关于IP欺骗一般只用在内网,不管你在内网如何欺骗,经过网络地址转换后到了外网上的IP地址表现就是你的公网的IP,除非你一开始就设置成公网的IP地址,但这个一般都不可能。这个问题体现提问者对于网络知识的理解还不深入。

            以上问题反映了在学习性能测试人员的一个比较普遍的现象,缺乏必要的知识积累、知识面不足,但又由于学习兴趣或工作压力期望急于求成,由此而形成这样一个矛盾的局面。

            在我看来,性能测试是一项综合性很强的工作,甚至可以作为一项工程来看待。

            从性能测试的知识体系来看,性能测试需要掌握性能测试的基础知识、业务知识、开发相关知识、以及性能测试工具。

            基础知识包括性能测试的原理、常见的测试类型、方法、策略,如何进行一个计划、设计、实施、分析等性能测试过程。没有性能测试基础知识,一切简单的性能测试在你手上都将出现各种问题,测试交流将变得难以沟通,同时性能测试的成功率将大大降低。

            业务知识通常都被忽略了。性能测试要基于被测系统的应用场景才有实际的价值,测试场景对性能测试结果有决定性的影响,因此测试场景的设计是非常关键的,场景的设计需要和业务应用结合起来。在一些比较正规的性能测试过程中,会有业务人员配合一起做性能用例设计的。

            开发相关的知识也是必须具备的知识,通常在这方面也是我们最大的缺点。这方面的知识包括操作系统数据库、应用服务器、中间件、网络等,每一个都是一门很深的学问,而要求性能测试人员都精通好像也不太现实。但起码的知识还是需要掌握的,比如通常有哪些参数需要监控和调整,它们之间是如何通信和运作的,某一方面知识的欠缺都可能导致测试模拟不准确或问题定位不充分,没有这些知识的支撑性能测试将变得难以下手或者学习工作的进展都会有很大的影响。

            测试工具的应用,这个是目前学习的焦点。只有在前面3点的基础上,采用合适的测试工具,才有助于测试目标的达成。


            从另外的角度分析,性能测试又可以分为技术、方法和管理方面的范畴。没有方法的指导光有技术那是行不通的,那是有勇无谋的体现。同时性能测试经常作为一个独立的阶段和活动,更需要用项目管理的方法进行,比如一个在客户现场的性能测试验收测试,与客户进行交流、时间计划的制定、测试进度的控制、测试脚本和测试数据的版本管理、各种资源的谐调等,都是需要用管理的思想进行的。

            从以上分析可以看出,由于性能测试工作需要具备这么多的知识,因此在一定程度上也成为了性能测试的门槛。这个综合的门槛将会成为很多性能测试新手入门的一道障碍,要突破这道障碍,建议结合自己的知识体系有针对性地去学习和提高。

            性能测试是一个技术与方法并重的工作,目前论坛上多谈技术,少谈方法,很多人甚至在没有任何性能测试基础知识的情况下就埋头苦学测试工具,我觉得是不应该的。我们应该意识到,测试工具只是性能测试中的一部分,仅是为达到性能测试目的而采用的一种手段。性能测试对于我们最大的价值在于方法和经验,我们学习的目标是整个性能测试过程上方法学的东西,而不是掌握具体某个测试工具。LoadRunner并不是万能的,在什么情况下应该采用什么工具才能达到最佳的效果,需要我们去判断。

            另外,学习需要有一个循序渐进的过程,性能测试需要长时间的知识积累,没有什么捷径可言。从学习效率和职业发展方面考虑,本人不太建议没有工作经验的测试新手一上来就扎进性能测试之中去,这样将花费你更多的时间精力去学习,是一种事倍功半的效果。

            不知深浅乱谈一通,说得不对的,请指正。

  • 性能测试工具之研究

    2007-07-07 00:44:23

    性能测试工具之研究

    来自http://www.51testing.com 作者:王玉亭

    【摘要】 本文在分析市场上已有的商用的性能测试工具实现原理和体系架构的基础上,提出了利用现有的开源代码构建开源的性能测试工具思路。

    【关键词】 性能测试、 Vugen 、 Conductor 、 Player 、 Analysis

    •  性能测试的意义

    追求更高的质量和更高的性能是人类的天性。 “ 更高,更快,更强 ” 的奥运会是对人类自身运动能力的测试。同样,人类也在追求我们工作生活中不可或缺的 IT 系统能够提供更快更强的服务。目前 IT 系统已经称为各个企业运转业务时最重要的系统之一。对 IT 历史稍微有所了解的人都知道, IT 系统经过早年的一个人使用的单机系统时代,几十个人使用的局域网中的客户机服务器系统时代,到现在服务成千上万用户的跨广域网的庞大系统时代。 IT 系统发展中的最明显的特征之一就是所谓的 “ 数据大集中 ” ,即数据越来越集中到后台的服务器中,系统同时为成百上千,乃至上万的用户提供服务。这样的例子在银行、保险、电信公司中随处可见。随着企业业务量的加大,其 IT 系统承载的负荷越来越重,系统性能的好坏严重影响了企业对外提供服务的质量。对 IT 系统的性能进行测试和调优越来越引起企业的重视。

    目前,典型的企业 IT 系统的架构如下所示:

     

    这样的系统由客户端、网络、防火墙、负载均衡器、 Web 服务器、应用服务器 ( 中间件 ) 、数据库等等环节组成,根据木桶原理,即木桶所能装的水的量取决于最短的那块木板,整个系统的性能要得到提高,每个环节的性能都需要优化。在这样的 IT 系统中,每个环节的都是一个很复杂的子系统,对其调优都是一门专门的技能。 Oracle 数据库的调优就需要专门的技能和多年的经验。对于整个 IT 系统的调优,其复杂程度更是急剧增加。因此 IT 系统性能测试调优是一个复杂的项目,需要拥有各种专门技能的专家组成小组来完成。这些专家包括操作系统专家、网络专家、数据库专家、应用服务器专家、应用软件和业务专家等等。

    虽然性能测试是一项很复杂和专业的工作,但是由于企业 IT 系统的重要性,保证其性能的稳定对于企业对外提供优质服务越来越得到企业的重视。性能测试服务的市场正在快速发育中。研究系统性能测试越来越有意义。

    要保证性能测试项目的高质量,必需依赖两个重要的因素:人和工具。具有多年经验的高素质的专家小组是保证性能测试的最重要的因素。另一方面,功能全面、使用灵活的性能测试工具对于加速性能测试,提高测试质量和效果也是必不可少的。

    现在有很多种性能测试工具,从功能简单单一的开放源码的软件到昂贵的商业性能测试工具。本文论述了性能测试工具的一般体系架构和技术要点,并探讨了利用已经存在的开放源码的软件整合出一套开源的优质的性能测试工具的可行性。

    •  性能测试工具综述

    性能测试的主要手段是通过产生模拟真实业务的压力对被测系统进行加压,研究被测系统在不同压力情况下的表现,找出其潜在的瓶颈。因此,一个良好的性能测试工具必需能做到以下几点:

    •  提供产生压力的手段

    •  能够对后台系统进行监控

    •  对压力数据能够进行分析,快速找出被测系统的瓶颈。

    产生压力的手段,主要是通过编写压力脚本,这些脚本以多个进程或者线程的形式在客户端进行运行,来模拟多用户对被测系统的并发访问,以此达到产生压力的目的。由于一台普通的 PC 机可以轻易产生几百乃至上千个进程或线程,通过使用若干台 PC 机,就可以轻易模拟出成千上万个并发用户。压力脚本执行的功能和被测系统客户端软件执行的功能应该一样,从而产生真正的业务压力。 编写压力脚本的工作实际上就是重新编写客户端软件。为了快速达到编写脚本的目的,采用的最有效的方式是通过性能测试工具录制客户端软件和服务器之间的通讯包,自动产生脚本,然后在自动生成的脚本的基础上进行少量修改,如:关联动态内容,指定批量测试数据等。根据经验,压力脚本的准备工作往往占据整个性能测试项目的 50% 的时间和工作量。 因此,能否提供录制和自动产生脚本的功能是性能测试工具最主要的评价指标之一。

    压力脚本的方式给我们提供了模拟各种压力状况的有力手段,通过人为制造各种类型的压力,我们可以观察被测系统在各种压力状况下的表现,从而定位系统瓶颈,作为系统调优的基础。因此,提供丰富的对后台系统进行监控的手段是性能测试工具第二个最主要的评价指标。监控应该不在被测系统上安装任何软件,否则的话,为了监控而引入的 “ 代理 ” 之类的小软件将给被测系统引入新的可变因素,一方面造成了测试结果的不准确,另一方面会给用户的系统的稳定性可能造成影响,从而导致用户的反感和拒绝。目前,各种监控手段大都采用所谓 “ 无代理 ” 的方式,即不在被测系统上安装任何软件,仅仅通过改变被测系统的配置,就可以对被测系统进行监控。需要监控的部件多种多样,包括操作系统、数据库、中间件、应用系统、安全模块、网络、防火墙等等。

    一组压力测试运行完毕后,我们会得到详尽的性能数据。这些数据包括最终用户的响应时间,后台系统各个部件的运行数据。这些数据的量非常大,往往包括几千个变量的运行曲线,大小可能达到上 G 的规模。靠人工去分析这些数据几乎是不可能的,性能测试工具必需提供数据分析工具,帮助性能测试人员去阅读、解读和分析数据,辅助测试人员定位系统的瓶颈。数据分析工具是保证最终测试成果的手段,因此它是性能测试工具中最重要的部分之一。

    目前已经存在的性能测试工具林林总总,数量不下一百种,从单一的开放源码的免费小工具如 Aapache 自带的 web 性能测试工具 ab 到大而全的商业性能测试软件如 Mercury 的 LoadRunner 等等。任何性能测试工具都有其优缺点,我们可以根据实际情况挑选用最合适的工具。

    前面已经指出,性能测试是一项复杂的工作,一个性能测试项目的质量如何,测试人员的素质、能力和经验是最关键的因素。拥有世界上最先进的 CT 扫描仪并不能让你成为一个优秀的医生。不过, “ 工欲善其事,必先利其器 ” , 拥有一套自己非常熟悉,功能全面、质量可靠的性能测试工具对于从事性能测试的人员非常有吸引力。在商业性能测试软件中,大多价格非常昂贵。由于大多数性能测试工具是按照并发用户数收取费用,因此要获得大的并发量的价格是很高的。虽然存在很多免费的性能测试工具,但其功能不足,彼此不成系统,不能灵活搭配使用。

    一套功能全面的性能测试工具的开发工作量是非常大的,这也是为什么商业性能测试软件价格昂贵的主要因素之一。由于互联网和开放源码运动的发展,性能测试工具的各种功能都以各种形式的开源软件存在了。 如果我们设计出一套合理的架构,在统一的架构下整合各种缺乏系统性的开源工具软件,使之能够彼此配套,搭配出一套功能全面、质量可靠,而且是开放源码的性能测试工具是完全有可能的。

    本文的下面部分具体论述性能测试工具的基本框架和技术要点,希望热爱编程,希望对开放源码运动有所贡献的读者能从本文的论述中获得一些启发,沿着作者的思路继续往前行。

    •  性能测试工具的体系架构

    作者对性能测试工具 LoadRunner 比较熟悉,通过对 LoadRunner 的了解和评估,作者设计的性能测试工具体系架构如下图所示:

    性能测试工具的组成部分有如下几个:

    •  虚拟用户脚本产生器 Vugen(Virtual User Generator)

    •  压力调度和监控系统 Conductor

    •  压力产生器 Player

    •  压力结果分析工具 Analysis

    通常,进行性能测试项目的一般步骤如下:

    •  用户确定需要录制的交易,通过用户操作和 Vugen 的录制,记录并生成自动化脚本。

    •  修改脚本,确定脚本能够回放成功。

    •  Conductor 是一个集中控制平台,它和压力产生器 player 互连,指定脚本在 player 上的分配,并控制 player 向被测系统的加压方式和行为。

    •  Conductor 同时负责搜集被测系统的各个环节的性能数据。各个 Player 会记录最终用户响应时间和脚本执行的日志。

    •  压力运行结束以后, Player 将数据传送到 Conductor 中, Conductor 负责将数据汇总。

    •  数据分析工具 Analysis 读取压力测试数据,进行分析工作,确定瓶颈和调优方法。

    •  针对性地进行系统调优,重复进行压力测试,确定性能是否得到提高。

    •  重复以上 3-7 步,逐步提高系统的性能。

    鲁制脚本的工具虚拟用户产生器 Vugen 实际上是一套开发调试工具。 Conductor 是一个框架程序和监控程序,它负责将 Vugen 开发的脚本以多进程 / 多线程的方式在 Player 机器上运行。为了产生更大的压力, Conductor 必需支持集群功能,理论上 Conductor 可以和任意多台 Player 机器互连,以便产生足够大的负载压力。 Conductor 同时实现无代理方式的监控功能,可以监控各种主流的软件,并且提供对不支持的软件进行监控的二次开发的手段。 Analysis 实际上是一个数据分析工具,用于事后的数据分析,它可以安装在任何 Windows 平台的机器上。下面我们论述每个部件的技术要点。

    •  虚拟用户产生器 Vugen

    虚拟用户产生器通过录制客户端和后台服务器之间的通讯包,分析其中的协议,自动产生脚本。用户在自动产生的脚本的基础上进行修改,从而快速开发出一个逻辑功能和客户端软件完全一样的压力脚本程序。

    录制的技术主要是通过 proxy 的方式来实现的,如下图所示:  

    Vugen 根据对捕获的数据的分析,将其还原成对应协议的 API 组成的脚本。由于 Proxy 源程序的获得非常容易, Vugen 的主要的技术要点是 如何根据捕获的数据包来反解析成对应的网络协议 。通常捕获的数据包为 TCP 数据流,我们可以很容易的生成 socket 层次的脚本,类似如下示例:

    int main( int argc, char** argv)

    {

    char buf[BUF_MAX_LEN];

    int socket = 0;

    socket = connect(“IP=192.168.52.65”, “Port=3200”, TCP);

    getbuffer(buf, “trace.dat”, 1, SEND);

    send(socket, buf);

    receive(socket, buf);

    getbuffer(buf, “trace.dat”, 3, SEND);

    send(socket, buf);

    receive(socket, buf);

    ……

    close(socket);

    }

    其中 trace.dat 包含着录制时捕获的数据包,按照 “ 发 - 收 - 发 - 收 - 发 - 收 ” 的顺序排放。

    毫无疑问,这样的脚本按照记录的收发过程来回放,但是它的最大的缺点是处于太底层。要分析和修改 socket API 的脚本以及数据包的具体内容将是一个繁重而且烦人的工作,进行关联的工作的难度也将大大提高。客户端程序往往是利用更高层的应用协议 API 编写的,客户端软件的编写者也不一定对 socket-API 组成脚本进行修改。因此, Vugen 应该尽可能地产生更高层网络协议的脚本 ,方便用户的阅读和修改工作。

    以 Tuxedo 应用为例,对于 Tuxedo 应用,一次典型的 Tuxedo 业务调用的序列为:

    tpinit(….) // 和后台建立连接

    tpcall(….) // 向后台发起交易请求

    tpterm(…) // 断开和后台的连接

    这三次 api 调用将产生 TCP 层的 7 次收发动作, Vugen 必需根据这 7 次的收发,还原产生 Tuxedo-API 的调用序列。

    由于对于不同的应用层协议,只能分别开发,因此, Vugen 支持的网络协议的多少是衡量性能测试工具的主要指标之一。

    当然, socket 方式是一切应用层协议的基础, socket 脚本是一种通用的方式。对于 Vugen 不支持的应用层协议只能通过 socket 层次来录制。因此 Vugen 能生成 socket-API 脚本是其最基本的功能。

    VuGen 产生的脚本应该应该是跨平台的,因此它应该提供 C/Java 两种语言的方式,支持各种平台的 C/Java 编译器。脚本可以在 Windows/Unix/Linux 上运行, Player 运行的机器既可以是 Windows 平台,也可以是 Linux, FreeBSD, Solaris, AIX 和 HP-UX 等平台,这样会方便用户选择机器作为 Player 。这一点非常重要。

    由于 Vugen 支持的每种应用层协议必需单独开发,在设计 VuGen 的软件体系架构时,应该采用插件的方式来设计网络协议的解析器。这部分的设计借鉴了 Apache 的 module 设计思想,可以让任何对开发协议解析器感兴趣的开发者在一个统一的框架下开发。

    VuGen 的体系结构如下图所示:

     

    Vugen 的体系结构分为三部分:

    •  第一部分为底层 proxy 录制器 , 负责捕获客户端和服务器之间通讯的数据包,这样的软件在开放源码的世界里面随处可见,而且非常成熟。 我们只要移植过来就可以使用。

    •  第二部分是界面部分,提供脚本编辑、调试和运行功能,这部分可以用 Visual C++/MFC 实现 Windows 平台版本和 Java/AWT 实现 Unix 版本。

    •  第三部分是以插件的形式提供的分析各种网络协议的解析器。开发这类插件的强有力的开发工具为 lex 和 yacc 。

    •  Proxy 二次捕获的问题

    Vugen 的 Proxy 方式需要解决的一个问题是二次捕获数据包的问题。

    早期的网络服务器程序对外提供一个固定端口,客户端仅仅和这个端口通讯就可以了。这对于 proxy 录制非常容易。但是现在很多服务器程序为了提高对客户端并发量的支持,采用两个端口通讯的方式。如下图所示:

     

    整个通讯的过程如下:

    •  第一步:客户端将请求发往 Proxy 录制器。

    •  第二步: Proxy 录制器将请求发往真正的服务器的指定端口,即图中的 3200 端口。

    •  第三步:服务器机器的 3200 端口返回数据包给 Proxy 录制器。该数据包中包含了下一次通讯的目的地址,形式为 IP:Port 。很显然,这里的 IP 数据为真正服务器的 IP 地址。

    •  第四步, Proxy 录制器把请求返回给客户端。

    •  第五步,客户端根据提供的 IP:Port 信息直接把请求发往真正的服务器,不再经过 Proxy 录制器。

    •  第六步:以后的通讯只是客户端和服务器之间的通讯了, Proxy 录制器是无法捕获这些通讯包了。

    因此一般的 Proxy 录制器只能捕获头两个收发的数据包。 这个问题更一般的情形的例子是 HTTP 的 redirection 功能。第二次通讯可能发往另外一台机器了。 Proxy 录制器必需解决这个问题。

    •  关联的问题

    客户端和服务器之间的通讯,有一部分是数据是动态的,每次通讯都不一样。 Proxy 录制器在录制的时候是无法区分哪些是静态的信息,哪些是动态的信息,所有的信息都以 hard-coded 的方式记录下来。但是在回放的时候,如果有些信息不改变,那么脚本是不能执行成功的。考虑如下情形:

     

    如上图所示,用户 jojo 以 jojo/bean 的账号 / 口令登录某一 web 服务器,查询某产品的信息,由 Vugen 录制交易的全部通讯包。 web 服务器返回给 jojo 一个动态的会话 ID: SessionID@12345 ,作为这次登录的会话标识。由于 Vugen 无法知道哪些信息是动态的,它会照单全收的方式,把所有的数据就记录下来。接着 jojo 根据 Web 服务器告诉他的 SessionID 去查询产品列表,交易可以正常执行下去。

    我们会观察到,当 Vugen 根据捕获的通讯包生成 http 脚本的时候, SessionID 是 Hard-coded 的,即 “ 写死 ” 在程序里面的。当我们不加修改的回放该脚本的时候,会出现什么问题呢?如下图所示:  

    按照录制时候的脚本, jojo 以 jojo/bean 登录后, Web 服务器返回给 jojo 一个动态会话 ID: SessionID@23456 ,这个值已经不是录制时候产生的 SessionID@12345 了,而是新的值: SessionID@23456 。那么脚本根据记录的 SessionID 的值,仍然会使用 SessionID@12345 去执行下面的查询交易。由于会话 ID 是有时效性的,用户退出系统后,其 SessionID 会失效,那么,服务器会给出一个 “SessionID 失效 ” 的错误,从而导致脚本无法正常执行下去。

    对于上面的问题的通用解决方法如下图所示:

     

    在第一次从服务器得到 SessionID 的时候把其放在一个变量 <session_id> 里面,在后面脚本访问服务器的语句里面,把所有的 ”SessionID@12345” 替换为变量 <session_id> 就可以圆满解决这个问题。

    这种问题在任何系统都是非常常见对外问题。其通用的模式是: “服务器返回给客户端一些动态变化的值,客户端使用这些值去访问服务器的时候,不能把这些值写死在脚本里面,而应该存放在一个变量里面。” 这就是关联的概念。

    关联的工作往往占据开发脚本的大部分时间,因为我们必需针对每一个具体的系统进行细致的分析,确定其需要关联的动态信息。为了快速开发脚本, Vugen 必需提供帮助我们关联的手段,最好做到自动关联。自动关联的方法有三种:

    •  在录制之前设定辨别规则,录制完毕,产生脚本的时候根据规则识别出需要关联的动态内容,从而产生正确的脚本。

    •  录制完毕回放一遍,把回放结果与录制结果进行自动对比,确定动态信息,进行自动关联。

    •  录制两个一模一样的脚本,对比其中的差异来确定需要关联的动态信息,然后进行关联。

    自动关联的功能是否完整可靠,关系到我们能否借助 Vugen 快速开发出符合要求的脚本,因此关联也是 Vugen 中非常重要的功能。

    •  脚本的问题

    Vugen 产生的最终结果是以源程序方式存在的脚本。为了编译该脚本,用户可以选用对应的编译器,这不是 Vugen 的功能。建议 Vugen 产生脚本的时候应该生成对应的 Makefile 和 build.xml ,允许用户以流行的 make 和 ant 命令来编译 C 和 Java 的脚本。关于 make 和 ant ,读者可以在互联网上查询相应的内容。

    Vugen 自动产生的脚本应该支持两种语言, C / Java 。很显然, Vugen 不可能产生一个脚本运行的全部的代码,它需要额外的函数库的支持。譬如,通过录制 Tuxedo 协议产生的脚本应该是以 Tuxedo-API 的形式出现的。为了能够编译运行脚本,必需把 Tuxedo 的函数库连接到脚本里面。目前动态库的技术应用非常广泛,因此为了运行 Tuxedo 脚本,必需在 Vugen 和 Player 机器上安装相应的 Tuxedo 客户端软件,因为它包含相应操作。其它网络协议也存在这个问题。对于 http 协议,已经有很多函数库。 Vugen 产生的 http 脚本应该支持主流的函数库。这样带来的好处是我们不需要自己开发 http 函数库,可以直接引用已经经过实践证明了的质量可靠的函数库。选择支持何种函数库,需要慎重选择,我们应该选择应用最广泛的函数库。例如:关于 http 函数库,可以采用 www.w3c.org 提供的 libwww ,该函数库是开源的,质量可靠,远胜于我们自己开发。

    •  Conductor Player 部分

    Conductor ,我们称为 “ 指挥家 ” ,它是整个压力测试的核心。 Player 是产生压力的负载产生器,它们以进程或者线程的方式运行由 Vugen 生成脚本。 Player 如何运行脚本,由 Conductor 来决定。这好比一个交响乐队在演奏。 Player 就是各种管弦乐演奏者, Conductor 是指挥者。

    Conductor 和 Player 实际上是一套框架程序。具体执行什么功能,是由脚本来完成的。 Conductor 和 Player 的体系结构如下图所示:

     

    如上图所示, Conductor 上面有若干进程 / 线程。每种进程的作用如下:

    •  Center 进程是整个调度的核心进程,它负责联系和用户界面打交道的工作。

    •  Agent 进程负责和远端的 Player 机器中对应的 Agent 进程通讯。负责把编译好的脚本传送到 Player 机器上。在脚本运行的时候,定期从 Player 机器上获取 Player 的运行状态,每个虚拟用户运行的日志。

    •  Monitor 进程负责对被测试系统的各个环节进行监控,并把监控的内容一方面写入 Conductor 机器的本地磁盘,另外一方面把监控的内容传送给 Center 进程,实时地显示在用户界面上。

    Player 的进程有两种,一个是 Agent 进程,一个是 Player 进程。 Agent 负责和 Conductor 机器通讯,它根据 Conductor 的指示,在本机器上派生出指定数目的 Player 进程,这些 Player 进程负责具体执行相应的脚本。 Player 进程个数就是虚拟用户的个数。

    Player 需要解决的一个问题是 IP 问题。为了防止黑客的攻击,某些后台的负载均衡设备一旦发现来自某一个 IP 的请求特别频繁时,就会拒绝为该 IP 提供服务。这样的功能造成的结果是 Player 无法把真正的压力加到后台系统中。解决方法就是在 Player 机器上伪装多个 IP 地址发送请求。这项技术称为 IP 欺骗 (IP Spoofling) 。 Conductor 和 Player 必需实现该项功能。

    •  Conductor Player 的技术要点

    关于 Conductor 和 Player 的技术要点有哪些,目前我还没有做深入的研究工作,但是我认为其技术要点主要涉及多进程 / 线程的编程,网络编程技术。可能这里面最大的难点是监控问题。当把被测系统的各个环节都监控起来,需要监控的参数会有成百上千个。如果采用集中式监控的方式,采集数据本身就对系统造成很大的影响,所以必需支持分布式监控方式。由于采集的数据是来自不同机器上的,由于各种的延迟,数据之间的时间同步将是一个重大的问题。

    关于监控,还需要进一步的研究。

    由于 Player 是没有界面的,是后台运行的程序,为了保持其可移植性,建议采用 Java 语言开发。

    Player 和 Conductor 之间的网络协议不一定重新开发,可以使用成熟的 Http 1.1 ,方便在性能测试时调试 Player 和 Conductor 之间可能出现的通讯问题。

    •  数据分析工具 Analysis

    该工具是一个纯数学工具软件,目前市场上已经存在了大量负责数据处理的软件,如 Matlab 等。可以将压力产生的数据直接导入其中进行处理。所以只要提供开放的数据接口就可以了,无需自己开发独立的性能数据分析软件。

    即使 Analysis 需要开发,应该开发一些知识分析的功能。譬如,我们搜集了很多 Oracle 的数据信息,这些数据之间往往有固定的联系。如果将这些联系的知识融入到 Analysis 当中,将会更好。但是这有点类似人工智能的意味,比较难。

    •  结束语

    本文是对性能测试工具的一般性论述,讨论了性能测试工具的基本功能和可能出现的技术要点。由于性能测试工具涉及的内容太多,作者只是大致论述。其中涉及细节当中仍然会有很多技术要点没有论述。只是希望本文对希望了解性能测试工具的读者有一个入门的帮助。

    一套功能全面的性能测试工具就象水管工经常携带的工具箱,里面充满各种工具,这些工具经过组合可以完成任何复杂的机械工作。完全从头开发这套工具箱,工程浩大,靠业余的编程爱好者是很难完成的。但是我们应该吸取 Unix“ 小而灵活 ” 的哲学思想,在一个大的框架下面开发或者利用已经存在的开源工具软件制造出一个个灵活的部件。当把这些部件组合起来以后,就是一个功能完整、质量可靠的性能测试工具箱

Open Toolbar