vlambda博客
学习文章列表

搭建私有PTS性能测试服务(四)

nGrinder的功能扩展

上一篇讲解了利用nGrinder进行一次性能测试的简单过程,相对于阿里云的PTS,还是有些许的差别,如果想实现跟阿里云PTS类似的效果,我们需要自定义增加一些模块,扩展一些方法。

类比阿里云PTS

我们先来看看nGrinder跟阿里云PTS之间功能上有何区别和类似的地方

功能


nGrinder 阿里云PTS
测试环境管理 没有统一管理测试机的地方,可测试任意机器,不需要事先定义 界面化统一 管理,可管理阿里云内网机器和公网机器,不在列表中的机器不可测
测试脚本管理 1. 可在线编辑脚本
2. 可配置URL生成脚本
3. 脚本支持jython和java语法
4. 可自定义扩展功能模块引入第三方库
5. 可在线调试脚本
6. 可通过工具录制脚本
1. 可在线编辑脚本
2. 脚本仅支持jython语法
3. 可自定义扩展功能模块引入第三方库
4. 可在线调试脚本
5. 可通过工具录制脚本
6. 可通过界面配置生成脚本
7. 可配置检查点
8. 可参数化脚本
测试场景配置 1. 可选agent数量定义虚拟用户数
2. 可阶梯式增加虚拟用户数
3. 可自定义DNS域名指向
4. 可自定义需要监控的机器
5. 可自定义收集需要的被测服务器数据
6. 可自定义进程数和线程数
1. 可选agent数量定义虚拟用户数
2. 可阶梯式增加虚拟用户数
3. 可自定义DNS域名指向
4. 只能监控在测试机列表中的机器
5. 不可以自定义需要收集的数据
6. 可通过目标模式自动配置虚拟用户数
7. 可配置阶梯式的停止虚拟用户数
测试任务管理 可配置立即或定时执行任务 1. 可配置立即或定时执行任务
2. 可实时监控性能指标
测试结果管理 主要监控的指标有:
CPU
内存
网络吞吐量
错误率
TPS
并发用户数
响应时间
最多5个自定义指标
主要监控的指标有:
CPU
内存
网络吞吐量
磁盘IO
错误率
TPS
并发用户数
响应时间
请求状态

操作流程

nGrinder 阿里云PTS
录制/编辑/调试脚本 -> 配置测试 -> 执行测试 -> 查看结果 录制/编辑/调试脚本 -> 配置场景 -> 配置任务 -> 启动任务 -> 查看结果

简单脚本对比

nGrinder

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#! /usr/bin/env python
# -*- coding:utf-8 -*-

# 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 admin
from net.grinder.script.Grinder import grinder
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
from net.grinder.plugin.http import HTTPPluginControl
from HTTPClient import NVPair

control = HTTPPluginControl.getConnectionDefaults()
# if you don't want that HTTPRequest follows the redirection, please modify the following option 0.
# control.followRedirects = 1
# if you want to increase the timeout, please modify the following option.
control.timeout = 6000

test1 = Test(1, "www.baidu.com")
request1 = HTTPRequest()

# Make any method call on request1 increase TPS
test1.record(request1)

class TestRunner:
# initlialize a thread
def __init__(self):
grinder.statistics.delayReports=True
pass

# test method
def __call__(self):
result = request1.GET("http://www.baidu.com")

# You get the message body using the getText() method.
# if result.getText().find("HELLO WORLD") != -1 :
# grinder.statistics.forLastTest.success = 1
# else :
# grinder.statistics.forLastTest.success = 0

# if you want to print out log.. Don't use print keyword. Instead, use following.
# grinder.logger.info("Hello World")

if result.getStatusCode() == 200 :
grinder.statistics.forLastTest.success = 1
elif result.getStatusCode() in (301, 302) :
grinder.logger.warn("Warning. The response may not be correct. The response code was %d." % result.getStatusCode())
grinder.statistics.forLastTest.success = 1
else :
grinder.statistics.forLastTest.success = 0

阿里云PTS

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# PTS Script Version 1.0
# Trunner auto-generated test script at Fri Oct 09 16:34:42 CST 2015

from java.lang import String
from java.util import Random
from java.util import Date

# PTS脚本SDK:框架API、常用HTTP请求/响应处理API
from util import PTS
from HTTPClient import NVPair
from HTTPClient import Cookie
from HTTPClient import HTTPRequest
from HTTPClient import CookieModule
from HTTPClient import ShutdownException

# PTS对参数化的相关支持
from com.aliyun.pts import DsvReader
from com.aliyun.pts import ParamManager

# 脚本初始化段,可以设置压测引擎的常用HTTP属性
PTS.HttpUtilities.setUrlEncoding('utf-8')
PTS.HttpUtilities.setFollowRedirects(True)
PTS.HttpUtilities.setTimeout(120000)
# PTS.HttpUtilities.setKeepAlive(False)
# PTS.HttpUtilities.setUseCookieModule(False)
# PTS.HttpUtilities.setProxyServer('localhost', 8888)
# PTS.Context.setParamDirectory("/Users/fei/Work/trunner/data")

# 支持socket测试, 如TCP\UDP等协议
# import socket

# 设置系统编码
import sys
reload(sys)
sys.setdefaultencoding('utf-8')


params = ParamManager.getInstance()

expiryDate = Date()
expiryDate.year += 10

class TestRunner:

# TestRunner对象的初始化方法,每个线程在创建TestRunner后执行一次该方法
def __init__(self):
self.threadContext = PTS.Context.getThreadContext()


# 主体压测方法,每个线程在测试生命周期内会循环调用该方法
def __call__(self):
PTS.Data.delayReports = 1

statusCode = self.action_20015009()
PTS.Framework.setExtraData(statusCode)

PTS.Data.report()
PTS.Data.delayReports = 0

def action_20015009(self):
statusCode = [0L, 0L, 0L, 0L]

headers = []
result = HTTPRequest().GET(u'http://www.baidu.com',[],headers)
PTS.Framework.addHttpCode(result.getStatusCode(), statusCode)
## statusCode[0]代表http code < 300 个数, statusCode[1] 代表 300<=http code<400 个数
# statusCode[2]代表400<=http code<500个数, statusCode[3] 代表 http code >=500个数
# 如果http code 300 到 400 之间是正常的
# 那么判断事务失败,请将statusCode[1:3] 改为 statusCode[2:3] 即可
if(sum(statusCode[1:3]) > 0):
PTS.Data.forCurrentTest.success = False
PTS.Logger.error(u'事务请求中http 返回状态大于300,请检查请求是否正确!')

return statusCode

# 调用施压引擎施压。第一个参数是事务名,可以为中文;第二个参数是执行事务方法的方法名;第三个统一写TestRunner
PTS.Framework.instrumentMethod(u'百度首页', 'action_20015009', TestRunner)

可以看出阿里云PTS跟nGrinder是多么的相似啊,阿里云PTS将操作体验做得更好,更容易上手了,但其原理都是一样的,功能其实也是基本一样的,从脚本中我们也可以看出,默认情况下,阿里云PTS判断测试是否通过是判断http响应码类型的数量,而nGrinder是判断http响应码是不是200,当然这些都是可以自行修改的,下面我们就讲讲怎么将nGrinder的功能扩展到跟阿里云PTS类似。

nGrinder引入自定义模块

有些人可能想要在脚本中使用 java 库或 python py 模块。这种情况下,nGrinder 支持这些文件的上传,用户可以使用无需任何系统配置的外部库。只需上传 jar 或者 py 文件到测试脚本文件相同位置的 lib 文件夹中即可。当执行测试时Lib 文件夹中的文件将自动传递给agent。

然后你只要像下面那样引用上传的 jar 或者 py即可。

from net.grinder.script import Test
from net.grinder.script.Grinder import grinder
from org.json.simple import JSONValue
from java.util import Random
from java.lang import String
# 下面这个库是位于 lib 文件夹中的。
from mpcCaller import NpcCaller

random = Random()Z

caller = NpcCaller("xx.xx.xx.15", 7090);
module = "tchat"
procedure = "chatBO/RelayCommand"…

扩展方法示例

文件名:PTS.py

# -*- coding:utf-8 -*-

# 性能测试框架公共方法
# @author 归根落叶
# @blog http://this.ispenn.com

#统计单页http code数量
def addHttpCode(statusCode,statusCodeList=[0L,0L,0L,0L]):
if statusCode < 300:
statusCodeList[0] += 1
if 300 <= statusCode < 400:
statusCodeList[1] += 1
if 400 <= statusCode < 500:
statusCodeList[2] += 1
if statusCode >= 500:
statusCodeList[3] += 1
return statusCodeList

#统计所有页http code数量
def sumHttpCode(statusCodeList,sumStatusCodeList=[0L,0L,0L,0L]):
for i in range(len(statusCodeList)):
sumStatusCodeList[i] += statusCodeList[i]
return sumStatusCodeList

#统计通过检查点的数量
def sumCheckPointStatus(checkPointStatus,checkPointStatusList=[0L,0L]):
if checkPointStatus == 1:
checkPointStatusList[0] += 1
else:
checkPointStatusList[1] += 1
return checkPointStatusList

测试脚本中引入模块

# -*- coding:utf-8 -*-

# 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 admin
from net.grinder.script.Grinder import grinder
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
from net.grinder.plugin.http import HTTPPluginControl
from HTTPClient import CookieModule
from HTTPClient import NVPair
import PTS #这里引入自定义模块

录制工具的安装和使用

nGrinder自带有录制脚本工具,看了简介感觉略有些麻烦,所以我没有尝试,不过因为阿里云PTS跟nGrinder的极度相似,所以录制工具也是可以通用的,因为生成的脚本略作修改即可使用。

安装插件

搭建私有PTS性能测试服务(四)

2、将下载的文件拖动至Chrome浏览器窗口,浏览器弹出确认新增扩展程序框,点击添加安装。

搭建私有PTS性能测试服务(四)

3、安装完成后浏览器右上角会出现PTS的icon。

搭建私有PTS性能测试服务(四)

录制脚本

对于复杂的业务,例如登陆、考试、订购、购买、发帖、回帖、退出等业务,由于捕获请求内容或者手工编写脚本工作量稍大,可以使用PTS基于Firefox(支持37及以下版本)和Chrome浏览器插件录制工具。通过使用此工具,用户在被测系统中进行手工操作业务,录制工具会将用户的操作行为进行录制,录制完成以后,自动生成脚本,根据业务规则可能稍微修改一下脚本,就可以运行脚本了,录制下来的脚本模拟了用户真实的操作行为,极大地方便用户的使用。工具安装后打开浏览器点击右上角PTS录制工具Logo,弹出录制工具框和浏览器

搭建私有PTS性能测试服务(四)

定义事务名,在浏览器输入URL进行访问操作,录制工具会自动记录访问操作过程中的HTTP请求

搭建私有PTS性能测试服务(四)

录制工具默认只显示HTML类型HTTP的录制请求,如需显示其他类型请求请点击内容过滤选择需要显示的类型请求。

录制完成后点击停止录制按钮,如果需要预览录制生成的脚本,请点击脚本预览按钮。

看看录制的脚本,是不是跟nGrinder自动生成的脚本很像呢,下篇就以一个小例子演示怎么结合录制工具和自定义的扩展模块进行测试达到阿里云类似的结果。


未完待续 下一篇将通过实例演示怎么用nGrinder进行性能测试