性能测试工具nGrinder配置及使用
一、安装nGrinder
机器配置要求:centos7 JDK1.8 tomcat7
wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-7/v7.0.93/bin/apache-tomcat-7.0.93.tar.gz
tar -zxvf apache-tomcat-7.0.93.tar.gz
cd apache-tomcat-7.0.93/webapps
wget https://github.com/naver/ngrinder/releases/download/ngrinder-3.4.2-20180830/ngrinder-controller-3.4.2.war
cd /opt/apache-tomcat-7.0.93/bin
vi catalina.sh
//添加下面内容:
JAVA_OPTS="-Xms600m -Xmx1024m -XX:MaxPermSize=200m"
启动tomcat
sh startup.sh
停止tomcat
sh shutdown.sh
访问http://ip:8080/ngrinder-controller-3.4.2
用户名密码为:admin admin
cd /opt/apache-tomcat-7.0.93/conf/
vi server.xml
//添加下面内容
<Context path="" docBase="/opt/apache-tomcat-7.0.93/webapps/ngrinder-controller-3.4.2" debug="0" reloadable="false"
crossContext="true"/>
重新启动tomcat
访问http://ip:8080
登录 admin admin
代理服务器(执行压测任务) 下载压测需要的agent
wget http://ngrinder.ceshis.com/agent/download/ngrinder-agent-3.4.2-localhost.tar
tar –xvf ngrinder-agent-3.4.2-localhost.tar
//(后台运行)
sh run_agent_bg.sh –o
被测服务器 下载监控monitor:
wget http://ngrinder.ceshis.com/monitor/download/ngrinder-monitor-3.4.2.tar
tar –xvf ngrinder-monitor-3.4.2.tar
测试代码:
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 java.util.Date
import java.util.List
import java.util.ArrayList
import HTTPClient.Cookie
import HTTPClient.CookieModule
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 admin
*/
(GrinderRunner)
class TestRunner {
public static GTest test //定义 GTest 静态变量 test
public static HTTPRequest request //定义 HTTPRequest 静态变量 request,用于发送 HTTP 请求
public static NVPair[] headers = [] //定义 NVPair 数组 headers ,用于存放通用的请求头数据
public static NVPair[] params = [] //定义 NVPair 数组 params ,用于存放请求参数数据
public static Cookie[] cookies = [] //定义 Cookie 数组 cookies ,用于存放通用的 cookie 数据
//定义了在 进程 被调用之前应执行的行为,初始化进程级数据
public static void beforeProcess() {
// HTTP请求超时时间,单位毫秒
HTTPPluginControl.getConnectionDefaults().timeout = 6000
//GTest是对测试记录进行统计的单元,脚本内,每个 GTest 对象都使用唯一的编号定义,可以有描述信息,
// 使用 GTest 的构造方法 GTest(int number, String description) 创建。如果创建了多个编号一样的对象,最后只会选用第一个
test = new GTest(1, "www.baidu.com")
//使用 new HTTPRequest() 创建 HTTPRequest 对象,用于发起 HTTP 请求
request = new HTTPRequest()
//请求头和请求参数,都是键值对对象 NVPair 类型的数组
// 设置请求头数据
List<NVPair> headerList = new ArrayList<NVPair>()
headerList.add(new NVPair("test_header", "test_header_value"))
headers = headerList.toArray()
// 设置请求参数
List<NVPair> paramList = new ArrayList<NVPair>()
paramList.add(new NVPair("paramname", "vaule"))
paramList.add(new NVPair("paramname2", "vaule2"))
params = paramList.toArray()
// 设置 cookie 信息
//可以通过 Cookie(String name, String value, String domain, String path, Date expires, boolean secure) 构造 cookie 对象,
// 然后存放到相应的数组中,方便后面使用
List<Cookie> cookieList = new ArrayList<Cookie>()
cookieList.add(new Cookie("username", "testname", "www.baidu.com", "/", new Date(), false))
cookies = cookieList.toArray()
// 记录日志
grinder.logger.info("before process.");
}
//定义了在 线程 被调用之前应执行的行为 初始化线程级数据
public void beforeThread() {
/*
* 使用 GTest 的 record(Object target, String methodName) 给 GTest 配置需要进行统计的方法,
* target 是脚本对象,这里是 this, methodName 是需要统计的方法名,通常都是被 @Test 注释的方法。
* 如果未配置,方法会正常执行,但是没有统计结果数据,
* 每一个被 @Test 注释的方法都是一个整体事务,在运行测试时,即便里面有 多次 HTTP 请求也只做一次统计。
* */
test.record(this, "test")
//配置延迟报告统计结果
grinder.statistics.delayReports=true;
grinder.logger.info("before thread.");
}
//定义每个被 @Test 注解的方法被执行前应执行的行为 初始化测试级别数据
public void before() {
request.setHeaders(headers)
//设置本次请求的 cookies
cookies.each { CookieModule.addCookie(it, HTTPPluginControl.getThreadHTTPClientContext()) }
grinder.logger.info("before thread. init headers and cookies");
}
//定义测试行为,被执行多次
public void test(){
HTTPResponse result = request.GET("http://www.baidu.com", params)
//根据请求的返回结果分别进行处理,如果是 HTTP 的返回状态码为重定向,则打日志,当然您可以做其他处理,
// 否则,使用断言 assertThat 方法进行结果验证,会自动进入统计结果中。
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));
}
}
}
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 java.util.Date
import java.util.List
import java.util.ArrayList
import HTTPClient.Cookie
import HTTPClient.CookieModule
import HTTPClient.HTTPResponse
import HTTPClient.NVPair
import org.slf4j.LoggerFactory
import ch.qos.logback.classic.Level
/**
* 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
*/
@RunWith(GrinderRunner)
class NumsPost {
public static GTest test
public static HTTPRequest request
public static NVPair[] headers = []
public static String body
public static Cookie[] cookies = []
public static List<String> LineList //存放参数文件记录
public static def rowNumber //参数行
@BeforeProcess
public static void beforeProcess() {
HTTPPluginControl.getConnectionDefaults().timeout = 6000
test = new GTest(1, "xxx.xx.xx.x")
request = new HTTPRequest()
// Set header datas
List<NVPair> headerList = new ArrayList<NVPair>()
headerList.add(new NVPair("Content-Type", "application/json"))
headerList.add(new NVPair("charset", "UTF-8"))
headers = headerList.toArray()
/*读取csv文件内容*/
LineList = new File("./resources/queryPackOrderDetail.csv").readLines("GB2312")
grinder.logger.info("before process.");
}
@BeforeThread
public void beforeThread() {
test.record(this, "test")
grinder.statistics.delayReports=true;
grinder.logger.info("before thread.");
}
@Before
public void before() {
request.setHeaders(headers)
cookies.each { CookieModule.addCookie(it,HTTPPluginControl.getThreadHTTPClientContext()) }
/**
* new Random().nextInt(lineList.size()) lineList.size()获取csv文件数据行数
* 为了避免获取到空的数据,建议将 lineList.size()替换为正整数,即csv文件中数据的行数.
*
* 如:buyerRowNumber = new Random().nextInt(10)
*/
rowNumber = new Random().nextInt(LineList.size())
/*获取csv文件中某一行的第一列数据*/
String MCode = LineList.get(rowNumber).toString().split(",")[0]
/*获取csv文件中某一行的第二列数据*/
String OCode = LineList.get(rowNumber).toString().split(",")[1]
//设置请求的入参--json格式
body = "{\"orderCode\":\"${OCode}\",\"memberCode\":\"${MCode}\"}"
grinder.logger.info("before thread. init headers and cookies");
}
@Test
public void test(){
HTTPResponse result = request.POST("http://xxx.xx.xx.x:xxxx/travelterminal/packOrder/queryPackOrderDetail", body.getBytes())
//println body
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));
}
}
}
参考文档:http://naver.github.io/ngrinder/