基于线上请求的性能测试系统CPC
来源:互联网 发布:python实战项目书籍 编辑:程序博客网 时间:2024/05/16 04:48
1.背景
测试人员在设计性能测试脚本时,HTTP请求中的参数往往根据个人经验设置,而测试人员水平参差不齐,设计往往具有局限性,不够全面,不能涵盖全线上真实的请求,故得到的性能测试结果不能够真实反映线上真实的情况。
使用线上环境下的HTTP请求检查软件性能的问题,通过Gor记录线上真实的请求,作为性能测试脚本的请求池,用请求池物料进行性能测试,能真实的反映软件系统在线上环境下的性能指标和问题。
2.概念
2-1.架构图
2-2.技术栈
请求池:
Gor:
HTTP 录制工具 https://github.com/buger/gor
Webdis:
A very simple web server providing an HTTP interface to Redis https://github.com/nicolasff/webdis
redis:
持久化缓存
性能测试工具:
nGrinder二次开发:
http://blog.csdn.net/neven7/article/details/50740018
Spring MVC
链路可视化:
watchman(微博APM)
influxDB:
时序化DB https://github.com/influxdata/influxdb
Grafana:
可视化工具 https://github.com/grafana/grafana
3.实现
3-1.请求池
使用Gor录制线上请求,根据线上请求,序列化成Json String, 持久化到redis;性能测试脚本根据key,获取到线上请求数据,进行压测。
为了方便部署请求池,将请求池docker化,使用如下命名,启动docker容器:
docker run -i -t --net=host gor-request-parser /bin/bash
开始录制线上数据:
sh gor_request_parser.sh 8080 60 GET your_api_name NONBASIC ip port参数介绍:8080:监听端口60:监听时间(秒)GET:HTTP METHODyour_api_name:过滤其他url,只保留your_api_name请求NONBASIC:非BASIC认证接口,参数BASIC为BASIC接口ip port:webdis服务
60s后, 请求数据持久化到redis中
*************************************************** gor http请求 序列化 http请求记录中,60 秒后,终止记录 ***************************************************Version: *************************************************** 记录结束, http请求序列化到请求池 @author hugang ***************************************************
redis的key为$date_$hostname_$url
value为Json Array,形如:
3-2.性能测试脚本
性能测试工具使用nGrinder,进行二次开发,请参考:http://blog.csdn.net/neven7/article/details/50740018;
性能测试脚本使用redis获取线上请求数据,依赖jedis、fastJson,在脚本lib中导入这2个jar包。
范例:
package org.ngrinder;import static net.grinder.script.Grinder.grinderimport static org.junit.Assert.*import static org.hamcrest.Matchers.*import net.grinder.plugin.http.HTTPRequestimport net.grinder.plugin.http.HTTPPluginControl;import net.grinder.script.GTestimport net.grinder.script.Grinderimport net.grinder.scriptengine.groovy.junit.GrinderRunnerimport net.grinder.scriptengine.groovy.junit.annotation.BeforeProcessimport 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.3import org.junit.Beforeimport org.junit.BeforeClassimport org.junit.Testimport org.junit.runner.RunWithimport HTTPClient.HTTPResponseimport HTTPClient.NVPairimport java.util.ArrayList;import java.util.Collections;import java.util.List;import groovy.json.JsonBuilderimport groovy.json.JsonSlurperimport com.alibaba.fastjson.JSONArray;import redis.clients.jedis.Jedis;/** * 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 hugang */@RunWith(GrinderRunner)class TestRunner { public static GTest test public static HTTPRequest request public static File file public static JSONArray jsonArray @BeforeProcess public static void beforeProcess() { HTTPPluginControl.getConnectionDefaults().timeout = 6000 test = new GTest(1, "压测ip") request = new HTTPRequest() test.record(request); // 读取请求池数据 Jedis jedis = new Jedis("redis ip", redis port); // redis key String key = "your key"; String jsonStr = jedis.get(key); jsonArray = JSONArray.parseArray(jsonStr); // grinder.logger.info(jsonArray.getString(0)); // grinder.logger.info("before process."); } @BeforeThread public void beforeThread() { grinder.statistics.delayReports=true; } @Test public void test(){ // 随机获取 int index = (int) (Math.random() * jsonArray.size()); String httpInfo = jsonArray.getString(index); def json = new JsonSlurper().parseText(httpInfo) String api = json.api Map param = json.param def nvs = [] param.each{ key, value -> nvs.add(new NVPair(key, value)) } // GET请求,wiki http://grinder.sourceforge.net/g3/script-javadoc/net/grinder/plugin/http/HTTPRequest.html // param1: uri, param2: queryData // HTTPResponse GET(java.lang.String uri, NVPair[] queryData) Makes an HTTP GET request. HTTPResponse result = request.GET("http://压测ip" + api, nvs as NVPair[]) 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)); // 请求返回的数据 // println(result.text); // 定义一个事务,接口返回数据校验,是否包含 assertThat(result.text, containsString("\"code\"")); } }}
3-3. 链路时间分布可视化
链路时间展示,启动web服务指定-javaagent为watchman agent,使用字节码增强,获取某一段时间内代码链路的分布时间。
请参考:http://blog.csdn.net/neven7/article/details/50980726
- 基于线上请求的性能测试系统CPC
- 基于lmbench的loongson1B 系统性能测试
- 基于Linux系统的性能测试
- 基于PXI平台的ESP系统性能测试平台
- 基于CompactRIO的嵌入式车载电性能测试系统研发
- 关于线上与线下性能测试结果的差异
- 关于线上与线下性能测试结果的差异
- 关于线上与线下性能测试结果的差异
- jmeter性能测试,基于scf框架的"java请求"接口封装、环境配置与测试
- java 线上问题定位与性能测试
- 高可用高性能系统(五)基于规则的请求路由
- 使用Btrace进行线上系统性能分析
- 基于CPC模型的精益服务运营管理
- jCpuTest 小小的 基于JAVA的 系统性能测试软件 首发啦~~
- 平衡边界作业算法并发仿真测试基于三层架构的Web系统的基准性能
- 基于Web的系统测试
- 基于Web的系统测试
- 基于Web的系统测试
- 简单的网络心跳包实现(如何确保client在线)
- Hadoop学习笔记---持续更新中。。。
- POJ3580 SuperMemo
- *图2
- 设计模式之:单例设计模式
- 基于线上请求的性能测试系统CPC
- So Easy[II]
- Openwrt一条命令把整个路由器搞蹦了
- Android Studio真机调试时不打印Log信息的解决方法
- 《java入门第一季》之面向对象(抽象类其实不抽象)
- #图3
- --生物技术制药课程文献调研报告撰写说明--
- POJ 3581 后缀数组
- iOS IPv6-only