性能测试初探---接口性能测试

(一).性能指标

PV: PageView, 页面浏览量或点击量,用户每次刷新即被计算一次;用户的一次刷新,给服务器造成了一次请求。

UV: UniqueVisitor, 访问你网站的一台计算机客户端为一个访客,0:00 - 24:00 内相同的客户端仅记一次。

TPS: Transaction Per Second 每秒系统处理的交易或事物的数量,衡量系统处理能力的重要指标。

RT: 响应时间,从客户端发送一个请求开始,到客户端接收到从服务器返回的响应结果结束所经历的时间,包括请求发送时间,网络传输时间和服务器处理时间三部分。

VU: Virtual User, 模拟真实业务逻辑步骤的虚拟用户,虚拟用户模拟的操作步骤被记录在虚拟用户脚本中,通常使用并发实现。

TPS波动: 系统性能依赖于特定的硬件、软件代码、应用服务、网络资源等,所以在性能场景执行期间,TPS可能会表现为稳定,或者波动,抑或遵循一定的上升或下降趋势。用TPS波动系数来记录这个指标值。

CPU: CPU资源是指性能测试场景运行的这个时间段内,应用服务系统的CPU资源占用率。CPU资源是判断系统处理能力以及应用运行是否稳定的重要参数。

Load: 系统正在干活的多少的度量,队列长度。系统平均负载,被定义为在特定时间间隔(1m,5m,15m)内运行队列中的平均进程数。

I/O: I/O可分为磁盘IO和网卡IO。

JVM: 即java虚拟机,它拥有自己的处理器、堆栈、寄存器等,还有自己相应的指令系统。Java应用运行在JVM上面。

GC: GC是一种自动内存管理程序,它主要的职责是分配内存、保证被引用的对象始终在内存中、把不被应用的对象从内存中释放。FGC会引起JVM挂起。

网速: 网络中的数据传输速率,一般以Byte/s为单位。通过ping延时来反映网速.

流量: 性能测试中,一般指单位时间内流经网卡的总流量。分为inbound和outbound,一般以KB为单位。

VU(并发压测用户数) = TPS(每秒执行事务数) × RT(响应时间)

在寻找合适的并发用户数上,建议使用PTS(淘宝性能自动化:https://pts.aliyun.com/lite/index.htm?spm=0.0.0.0.8t95Nt)的“梯度模式”,逐渐增加并发用户数,这个时候压力也会越来越大,当TPS的增长率小于响应时间的增长率时,这就是性能的拐点,也就是最合理的并发用户数;当TPS不再增长或者下降时,这个时候的压力就是最大的压力,所使用的并发用户数就是最大的并发用户数。如果此时的TPS不满足你的要求,那么就需要寻找瓶颈来优化。
性能测试初探---接口性能测试_第1张图片

a点:性能期望值

b点:高于期望,系统安全

c点:高于期望,拐点

d点:超过负载,系统崩溃

(二).LoadRunner统计接口性能数据

LoadRunner分成3步:
1. Create/Edit Scripts;
2. Run Load Tests;
3. Analyze Test Results;

第一步:编写脚本(GET请求)

新建 New Scrips, 选择Web(HTTP/HTML)协议,因为不是对页面测试,无需记录操作,在“Start Recording”弹窗中,选择Cancel。
手动编写脚本:

Action()
{
    web_set_max_html_param_len("10240");

    // 关键词Text的value值为在请求返回的结果中搜寻的字符串
    // 关键词SaveCount的value值为在结果中找到Text文本内容的个数
    web_reg_find("Text={\"statuses\":",
             "SaveCount=Count",
              LAST);


    // 自定义事务unread_friends_timeline_reload,起始点
    lr_start_transaction("unread_friends_timeline_reload");
    // basic认证,在头信息添加Authorization值,变量authorization参数化
    web_add_header("Authorization","{authorization}"); 
    // http请求
    web_custom_request("web_custom_request",
        "URL=http://ip:port/2/statuses/unread_friends_timeline.json?source=******",
        "Method=GET",
        "RecContentType=application/json",
        "Mode=HTTP",
        "EncType=application/x-www-form-urlencoded",
        LAST);

    // 判断结果是否包含预期文本,如果包含,则事务unread_friends_timeline_reload状态为LR_PASS
   if (atoi(lr_eval_string("{Count}")) == 1){

        lr_end_transaction("unread_friends_timeline_reload", LR_PASS);

        }

    else{

         lr_error_message("error=%s","errorContent");

         lr_end_transaction("unread_friends_timeline_reload", LR_FAIL);

         }

return 0;

}

按“F5”键运行脚本,Replay Log输出如下:

Virtual User Script started at : 2015-10-07 16:58:47
Starting action vuser_init.
Web Turbo Replay of LoadRunner 11.0.0 for WIN2003; build 9409 (Jan 11 2012 11:34:16)    [MsgId: MMSG-27143]
Run Mode: HTML      [MsgId: MMSG-26000]
Run-Time Settings file: "E:\unreadfeed\unreadfeedreload\\default.cfg"   [MsgId: MMSG-27141]
Ending action vuser_init.
Running Vuser...
Starting iteration 1.
Starting action Action.
Action.c(3): web_set_max_html_param_len was successful      [MsgId: MMSG-26392]
Action.c(6): Registering web_reg_find was successful    [MsgId: MMSG-26390]
Action.c(12): Notify: Transaction "unread_friends_timeline_reload" started.
Action.c(15): Warning -26593: The header being added may cause unpredictable results when applied to all ensuing URLs. It is added anyway   [MsgId: MWAR-26593]
Action.c(15): web_add_header("Authorization") highest severity level was "warning"      [MsgId: MMSG-26391]
Action.c(16): Registered web_reg_find successful for "Text={"statuses":" (count=1)      [MsgId: MMSG-26364]
Action.c(16): web_custom_request("web_custom_request") was successful, 91858 body bytes, 198 header bytes   [MsgId: MMSG-26386]
Action.c(26): Notify: Transaction "unread_friends_timeline_reload" ended with "Pass" status (Duration: 0.8905 Wasted Time: 0.6256).
Ending action Action.
Ending iteration 1.
Ending Vuser...
Starting action vuser_end.
Ending action vuser_end.
Vuser Terminated.

Action.c(26): Notify: Transaction “unread_friends_timeline_reload” ended with “Pass” status (Duration: 0.8905 Wasted Time: 0.6256). 表示脚本调试通过。

LoadRunner参数化设置可以参见:http://www.cnblogs.com/fnng/archive/2012/06/22/2558900.html

模拟POST请求:

web_custom_request中参数设置:”Method=POST”,“Body=属性名称=属性值&属性名称=属性值&……”,web_custom_request中Body中的属性值如果包含一些特殊字符,必须通过URL编码,否则Web服务器会返回500错误。

例子:

web_custom_request("web_custom_request", "URL=http://ip/2/statuses/update.json", "Method=POST", "RecContentType=application/json", "Mode=HTTP", "EncType=application/x-www-form-urlencoded", "Body=status=123&source=********", LAST);

第二步: Run Load Tests

自定义脚本之后,运行第二步,Run Load Tests, 弹出New Scenario小窗口,左下选择测试脚本,进入场景设计。

场景设置主要包括4部分,选择Global Schedule->Edit Action设置场景:

1.Initialize: VU初始化设置

2.Start Vusers: 定义多少个VU, 用户增长选择
(1)Simultaneously 同时;(2)每隔一定时间,增长用户

3.Duration: 运行时间设置

4.Stop Vusers: 终止VU的策略

场景设置结束后,点击左下Run, 点击Start Scenario,开始场景性能测试。

点击stop, 终止性能测试; 自动跳到第三步。

第三步: Analyze Test Results

结果展示,会有3份报告

(1)Analysis Summary: Statistics Summary, Transaction Summary,HTTP Responses Summary

(2)Averagee Response Time: Minimum, Average, Maximum, std.Deviation(标准方差), 单位:s

(3)Transactions per Second:Graph Minmum, Average, Graph Maximum, Graph Median, Graph Std. Deviatior

LoadRunner并没有提供响应时间的分布情况,只有最小,最大,平均,标准方差,90 Percent,如果需要统计50%,60%,70%,80%,90% RT的分布情况,需通过LR获取原始数据,通过Excel公式PERCENTILE计算:

在Averagee Response Time报告下,选择Windows菜单->Raw Data, 右侧出现Raw Data, 展开该选项,通过Transaction Name(值为脚本中自定义的事务名)获取接口响应时间原始数据Transaction Response Time,粘贴到excel中,假设原始数据都在一列(A2-A57),比如要获得50% RT, 则使用公式=PERCENTILE(A2:A57;0.5)得到结果,依次类推…

(三).业界性能测试工具

PTS:

阿里性能测试服务(https://pts.aliyun.com/lite/index.htm?spm=0.0.0.0.SpnIsn),在线Web服务,短板:只支持阿里云内网和公网,不支持内网。
帮助文档:https://home.console.aliyun.com/, 功能强大,实时展示事务成功和失败TPS、并发用户数(线程数)、平均响应时间等数据趋势分析图,CPU利用率、Load、内存、网络IO、磁盘IO等数据趋势分析图,测试脚本为Python。

PTS-AB-Jmeter-LoadRnner压测工具对比测试:
http://bbs.aliyun.com/read/236875.html?spm=5176.7189909.0.0.O14Ykp

开源工具:

1.Gatling:http://gatling.io/#/

Gatling is an open-source load testing framework based on Scala, Akka and Netty
High performance
Ready-to-present HTML reports
Scenario recorder and developer-friendly DSL

测试脚本为Scala, 短板:没有TPS数据,优点:结果图形化展示很清晰。
部分截图:
性能测试初探---接口性能测试_第2张图片
性能测试初探---接口性能测试_第3张图片
性能测试初探---接口性能测试_第4张图片

快速入门:http://gatling.io/docs/2.1.7/
官网下载太慢,已上传到csdn,下载地址:http://download.csdn.net/detail/neven7/9161447

2.nGrinder:http://naver.github.io/ngrinder/

nGrinder is a platform for stress tests that enables you to execute script creation, test execution, monitoring, and result report generator simultaneously. The open-source nGrinder offers easy ways to conduct stress tests by eliminating inconveniences and providing integrated environments.
nGrinder是NAVER(韩国最大互联网公司NHN旗下搜索引擎网站)开源的性能测试工具,提供war包,直接部个web服务,就能使用。
性能测试初探---接口性能测试_第5张图片
默认管理员账号:admin/admin
账号登入后,需要下载agent和monitor(注意下载的agent会有对应的账号信息,一个账号对应唯一的agent,其他账号登入不能使用其他人的agent,只能使用自己下载的agent):
性能测试初探---接口性能测试_第6张图片
安装在测试机上,monitor监控机器性能,agent执行性能测试;测试脚本为Groovy/Jython,测试脚本类似JUnit case,自定义了runner: GrinderRunner

package org.ngrinder;

import static net.grinder.script.Grinder.grinder
import static org.junit.Assert.*
import static org.hamcrest.Matchers.*
import net.grinder.plugin.http.HTTPRequest
import net.grinder.plugin.http.HTTPPluginControl;
import net.grinder.script.GTest
import net.grinder.script.Grinder
import net.grinder.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
// import static net.grinder.util.GrinderUtils.* // You can use this if you're using nGrinder after 3.2.3
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

import HTTPClient.HTTPResponse
import HTTPClient.NVPair

/** * A simple example using the HTTP plugin that shows the retrieval of a * single page via HTTP. * * This script is automatically generated by ngrinder. * * @author user */
@RunWith(GrinderRunner)
class TestRunner {
    public static GTest test
    public static HTTPRequest request

    @BeforeProcess
    public static void beforeProcess() {
        HTTPPluginControl.getConnectionDefaults().timeout = 6000
        test = new GTest(1, "www.baidu.com")
        request = new HTTPRequest()
        test.record(request);
        grinder.logger.info("before process.");
    }

    @BeforeThread 
    public void beforeThread() {
        grinder.statistics.delayReports=true;
        grinder.logger.info("before thread.");
    }

    @Test
    public void test(){
        HTTPResponse result = request.GET("http://www.baidu.com")

        if (result.statusCode == 301 || result.statusCode == 302) {
            grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode); 
        } else {
            assertThat(result.statusCode, is(200));
        }
    }
}

图形化设置参数:
性能测试初探---接口性能测试_第7张图片

结果显示:
性能测试初探---接口性能测试_第8张图片

官方wiki:http://www.cubrid.org/wiki_ngrinder/entry/user-guide

你可能感兴趣的:(性能测试)