流量回放框架jvm-sandbox-repeater的实践【入门使用篇】1 repeater安装与启动(初尝repeater-console)

​​​本章内容分为5部分进行介绍:背景与导读、重点词语解释、安装和工作原理篇、安装篇、启动篇、附加篇、附录篇。

背景与导读

对 jvm-sandbox-repeater 做了有一段时间的学习和调研,看到目前 repeater 相关的文章比较少,所以将自己这段时间了解和实践的内容整理出来,分享给大家。

入门使用篇主要是基于官方文档和 testerhome 其他的操作文档,对 repeater 的使用上的操作细节和配置做了补充说明,建议大家先按照官方的文档使用过了之后,再看这些文档,能够更好地理解文档内容。

笔记中的每一个篇都有建立在此前篇章的基础上,建议按照顺序阅读。
在这里记录下系列文章地址:

全链路压测引发的惨案-流量回放的实践(一)

(本文)

流量回放框架jvm-sandbox-repeater的实践【入门使用篇】1 repeater安装于启动(初尝repeater-console)

重点词语解释

一、jvm-sandbox与jvm-sandbox-repeater

JVM-SANDBOX

jvm-sandbox-repeater

简介JVM沙箱容器,一种JVM的非侵入式运行期AOP解决方案

基于JVM-Sandbox的录制/回放通用解决方案
jvm-sandbox-repeater是JVM-Sandbox生态体系下的重要模块,它具备了JVM-Sandbox的所有特点,插件式设计便于快速适配各种中间件,封装请求录制/回放基础协议,也提供了通用可扩展的各种丰富API。

目标群体

1. BTRACE好强大,也曾技痒想做一个更便捷、更适合自己的问题定位工具,既可支持线上链路监控排查,也可支持单机版问题定位。

2. 有时候突然一个问题反馈上来,需要入参才能完成定位,但恰恰没有任何日志,甚至出现在别人的代码里,好想开发一个工具可以根据需要动态添加日志,最好还能按照业务ID进行过滤。

3. 系统间的异常模拟可以使用的工具很多,可是系统内的异常模拟怎么办,加开关或是用AOP在开发系统中实现,好想开发一个更优雅的异常模拟工具,既能模拟系统间的异常,又能模拟系统内的异常。

4. 好想获取行调用链路数据,可以用它识别场景、覆盖率统计等等,覆盖率统计工具不能原生支持,统计链路数据不准确。想自己开发一个工具获取行链路数据。

5. 我想开发录制回放、故障模拟、动态日志、行链路获取等等工具,就算我开发完成了,这些工具底层实现原理相同,同时使用,要怎么消除这些工具之间的影响,怎么保证这些工具动态加载,怎么保证动态加载/卸载之后不会影响其他工具,怎么保证在工具有问题的时候,快速消除影响,代码还原

如果你有以上研发诉求,那么你就是JVM-SANDBOX(以下简称沙箱容器)的潜在客户。

沙箱容器提供:

1. 动态增强类你所指定的类,获取你想要的参数和行信息甚至改变方法执行

2. 动态可插拔容器框架

1. 线上有个用户请求一直不成功,我想在测试环境Debug一下,能帮我复现一下吗?

2. 压测流量不知道怎么构造,数据结构太复杂,压测模型也难以评估,有什么好的办法吗?

3. 不想写接口测试脚本了,我想做一个流量录制系统,把线上用户场景做业务回归,可能会接入很多服务系统,不想让每个系统都进行改造,有好的框架选择吗?

4. 我想做一个业务监控系统,对线上核心接口采样之后做一些业务校验,实时监控业务正确性。

如果你有以上的想法或需求,jvm-sandbox-repeater 都将是你的不二选择方案;框架基于JVM-Sandbox,拥有JVM-Sandbox的一切特性,同时封装了以下能力:

1. 录制/回放基础协议,可快速配置/编码实现一类中间件的录制/回放

2. 开放数据上报,对于录制结果可上报到自己的服务端,进行监控、回归、问题排查等上层平台搭建

项目简介

JVM-SANDBOX(沙箱)实现了一种在不重启、不侵入目标JVM应用的AOP解决方案。

沙箱的特性

无侵入:目标应用无需重启也无需感知沙箱的存在

类隔离:沙箱以及沙箱的模块不会和目标应用的类相互干扰

可插拔:沙箱以及沙箱的模块可以随时加载和卸载,不会在目标应用留下痕迹

多租户:目标应用可以同时挂载不同租户下的沙箱并独立控制

高兼容:支持JDK[6,11]

沙箱常见应用场景线上故障定位线上系统流控线上故障模拟方法请求录制和结果回放动态日志打印安全信息监测和脱敏JVM-SANDBOX还能帮助你做很多很多,取决于你的脑洞有多大了。

实时无侵入AOP框架

在常见的AOP框架实现方案中,有静态编织和动态编织两种。

静态编织:静态编织发生在字节码生成时根据一定框架的规则提前将AOP字节码插入到目标类和方法中,实现AOP;

动态编织:动态编织则允许在JVM运行过程中完成指定方法的AOP字节码增强.常见的动态编织方案大多采用重命名原有方法,再新建一个同签名的方法来做代理的工作模式来完成AOP的功能(常见的实现方案如CgLib),但这种方式存在一些应用边界:

侵入性:对被代理的目标类需要进行侵入式改造。比如:在Spring中必须是托管于Spring容器中的Bean

固化性:目标代理方法在启动之后即固化,无法重新对一个已有方法进行AOP增强

要解决无侵入的特性需要AOP框架具备 在运行时完成目标方法的增强和替换。在JDK的规范中运行期重定义一个类必须准循以下原则

不允许新增、修改和删除成员变量

不允许新增和删除方法

不允许修改方法签名

JVM-SANDBOX属于基于Instrumentation的动态编织类的AOP框架,通过精心构造了字节码增强逻辑,使得沙箱的模块能在不违反JDK约束情况下实现对目标应用方法的无侵入运行时AOP拦截。

repeater的核心能力是什么?
1. 通用录制/回放能力
无侵入式录制HTTP/Java/Dubbo入参/返回值录制能力(业务系统无感知)
基于TTL提供多线程子调用追踪,完整追踪一次请求的调用路径
入口请求(HTTP/Dubbo/Java)流量回放、子调用(Java/Dubbo)返回值Mock能力
2. 快速可扩展API实现
录制/回放插件式架构
提供标准接口,可通过配置/简单编码实现一类通用插件
3. standalone工作模式
无需依赖任何服务端/存储,可以单机工作,提供录制/回放能力


repeater的可以应用到哪些场景?
1. 业务快速回归
基于线上流量的录制/回放,无需人肉准备自动化测试脚本、准备测试数据
2. 线上问题排查
录制回放提供"昨日重现"能力,还原线上真实场景到线下做问题排查和Debug
动态方法入参/返回值录制,提供线上快速问题定位
3. 压测流量准备
0成本录制HTTP/Dubbo等入口流量,作为压测流量模型进行压测
4. 实时业务监控
动态业务监控,基于核心接口数据录制回流到平台,对接口返回数据正确性进行校验和监控

核心原理事件驱动、类隔离策略、类增强策略流量录制、流量回放

二、repeater-console 

官方的说明

jvm-sandbox-repeater 仅仅提供了录制回放的能力,如果需要完成业务回归实时监控压测等平台,后面须要有一个数据中心负责采集数据的加工、存储、搜索,repeater-console 提供了简单的demo示例;一个模块管理平台负责管理JVM-Sandbox各模块生命周期;一个配置管理平台负责维护和推送jvm-sandbox-repeater采集所须要的各种配置变更注意:目前项目代码默认启动standalone模式,不需要依赖任何服务端和存储,能够简单快速的实现单机的录制回放,控制单机模式的开关在~/.sandbox-module/cfg/repeater.properties 文件中的 repeat.standalone.mode=true //开启或关闭单机工作模式,关闭单机模式后,配置拉取/消息投递等都依赖repeater.properties中配置的具体url;如不想通过http拉取和消息投递的也可以自己实现BroadcasterConfigManager。稍后我们会公布一份录制回放所需的完整架构图以及jvm-sandbox-repeater在整个体系中的位置供大家工程使用做参考。

个人理解,要想在业务中使用,我们还得搞下 数据中心、模块管理 和 配置管理 。

【数据中心】:你存了那么多流量,总得有个存储和管理的地方吧,数据中心就是干这个活。要不光靠官方提供的那个透传 repeatId 的回放方法,只能回放单个流量,实际项目不够用。
【模块管理】:这个还不是太了解,个人理解是各个 plugin 的管理?
【配置管理】:就是之前试用时说过的只有一个 ~/.sandbox-module/cfg/repeater-config.json 配置文件,是不可能满足多个项目同时使用的需要的。所以需要有个配置管理,提供这方面配置的存储和修改能力。

步骤解析:

安装过程:(橙色标注部分)

第1步:用户先启动repeater-console服务,通过console提供的配置界面录制应用名、环境和录制接口

第2,3步:用户携带第一步总配置好的应用名和环境参数启动被监测应用,启动过程中repeater会注入到被监测服务中

第4步:启动中通过项目中的bin/repeater.properties配置信息,进行拉去第1步的配置信息进行心跳上报(即:把被监测服务记录到repeater-console中),为后面录制回放做环境准备,同时也方便用户可视画管理。

ps:第4步中的bin/repeater.properties配置地址配置的是repeater-console的部署地址(即指代的第5步)。

录制过程:(浅绿色标注部分)

第7步:用户请求到service

第8步:sandbox感知到请求

第9步:sandbox将感知到的请求通知repeater。

第10步:repeater对事件进行给过滤和采样计算,对满足录制条件的请求会记录请求、响应、子调用和响应,序列化成后通知repeater-console

第11步: repeater-console对序列化结果进行处理和保存

回放过程:(浅蓝色标注部分)

第12步:  用户请求repeater-console的回放接口,明确需要回放哪条录制数据

第13步: repeater-console通过调用repeater提供的回放任务接收接口下发回放任务

第14步: repeater在执行回放任务的过程中,会反序列化记录的wrapperRecord,根据信息构造相同的请求,对被挂载的任务进行请求并跟踪回放请求的处理流程,以便记录回放结果以及执行mock动作

第15步: 回放结束,repeater会将回放信息和结果序列化后通知repeater-console进行处理和保存

安装篇

一、jvm-sandbox-repeater部署结构和工程结构

1.1  jvm-sandbox-repeater部署后结构

PS:黑色部分是sandbox结构

 红色部分是安装 repeater结构

Linux/home/用户名/ Mac/Uaers/用户名/

.
├── bin
│   └── sandbox.sh
├── cfg
│   ├── sandbox-logback.xml
│   ├── sandbox.properties
│   └── version
├── example
│   └── sandbox-debug-module.jar
├── install-local.sh
├── lib
│   ├── sandbox-agent.jar
│   ├── sandbox-core.jar
│   └── sandbox-spy.jar
├── module
│   └── sandbox-mgr-module.jar
├── provider
│   └── sandbox-mgr-provider.jar
└── sandbox-module
├── cfg
│   ├── repeater-config.json
│   ├── repeater-logback.xml
│   └── repeater.properties
├── plugins
│   ├── dubbo-plugin.jar
│   ├── hibernate-plugin.jar
│   ├── http-plugin.jar
│   ├── ibatis-plugin.jar
│   ├── java-plugin.jar
│   ├── mybatis-plugin.jar
│   ├── redis-plugin.jar
│   └── spring-data-jpa-plugin.jar
├── repeater-bootstrap.jar
└── repeater-module.jar

1.2 jvm-sandbox-repeater 工程结构(源码)

jvm-sandbox-repeater git:(master) ✗ tree -L 2
.
├── LICENSE
├── Readme.md
├── bin
│   ├── bootstrap.sh 
│   ├── health.sh 
│   ├── install-local.sh # 本地的启动脚本 
│   ├── install-repeater.sh
│   ├── package.sh  # 本地的编译脚本 ,负责编译并把编译好的包copy到.sandbox-module下面去
│   ├── repeater-config.json  # 默认的配置文件
│   ├── repeater-logback.xml #日志配置
│   └── repeater.properties  # 配置文件 配置录制投递、回放地址、配置文件获取等信息
├── docs # 文档使用
│   ├── plugin-development.md
│   ├── slogan-demo.md
│   └── user-guide-cn.md
├── hessian-lite # 针对hessian 进行的修改,这个地方使用的时候可以针对自己的业务进行修改
│   ├── hessian-lite.iml
│   ├── pom.xml
│   └── src
├── pom.xml
├── repeater-aide # 这是diff 相关的东西
│   ├── pom.xml  
│   └── src
├── repeater-client # 这里放了spring容器相关的操作
│   ├── pom.xml
│   └── src
├── repeater-console # 这是一个web服务,主要是用于录制数据的接收、存储,提供配置页面服务
│   ├── Readme.md
│   ├── pom.xml
│   ├── repeater-console-common # 这是console的 工具包
│   ├── repeater-console-dal # 这是JPA的Dao层
│   ├── repeater-console-service #  主要是JPA的相关操作
│   ├── repeater-console-start # 这是console的controller
├── repeater-module # 这里就比较有意思了,是加载配置信息的,属于自定义的东西
│   ├── pom.xml
│   └── src
├── repeater-plugin-api  # 这是插件api,主要是一些Bean对象的定义
│   ├── pom.xml
│   └── src
├── repeater-plugin-core # 这是核心,录制、回放、Mock、序列化等相关的实现都是这里
│   ├── pom.xml
│   └── src
├── repeater-plugins # 这是官方提供的插件,但是用的时候需要自己改改
│   ├── dubbo-plugin
│   ├── hibernate-plugin
│   ├── http-plugin
│   ├── ibatis-plugin
│   ├── java-plugin
│   ├── mybatis-plugin
│   ├── redis-plugin
│   ├── repeater-plugins.iml
│   ├── socketio-plugin
│   └── spring-data-jpa-plugin
│   ├── pom.xml
└── travis.sh

二、安装sandbox和repeater

PS:安装时必须保证安装用户与被录制应用启动的用户一致。可以直接执行官方文档中的安装脚本,也可使用本地源码安装。本章使用源码安装

1.1 环境准备

目前安装和使用,需要 mac 或者 linux 系统下进行,如果在 windows 下进行可能会遇到安装路径出错导致安装失败或者运行失败的情况。

  • linux/Mac os
  • jdk 1.8+
  • maven 3.2+
  • 数据库 mysql 5.7+(repeater-console 可能用到)

PS:如果只是想简单运行,可以直接使用官方版本,参考官方用户手册,以standalone模式把玩。

1.2.1 本地源码安装

1、修改配置和源码信息

1).克隆源码到本地

# 克隆代码到本地

git clone https://github.com/alibaba/jvm-sandbox-repeater.git

2)、初始化数据库,初始化的sql文件在

/jvm-sandbox-repeater/repeater-console/repeater-console-dal/src/main/resources/database.sql

初始化成功,应该会创建了 repeater 这个数据库,且包括下面四个表:

3)、调整 console 工程中MySQL 的数据库配置信息

位置:/jvm-sandbox-repeater/repeater-console/repeater-console-start/src/main/resources spring.datasource.url=jdbc:mysql://数据库IP/域名:数据库端口/数据库名?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username=用户名 spring.datasource.password=密码

4)、repeater-console源码调整:

console代码在idea中启动时,不会报错,但是使用jar包启动时,页面会报异常,需要做如下调整。

- 位置 repeater-console/repeater-console-start/src/main/resources/velocity 
全局替换 #parse("/blocks 为 #parse("blocks 
解决资源文件引用找不到报错,这个替换有多处,都替换了就可以了

- 位置 repeater-console/repeater-console-start/src/main/java/com/alibaba/repeater/console/start/controller/page/ReplayController.java 
替换 return "/replay/detail"; 为 return "replay/detail"
解决跳转页面的问题

- 位置 repeater-console/repeater-console-start/src/main/java/com/alibaba/repeater/console/start/controller/test/RegressPageController.java 
替换 return "/regress/index"; 为 return "regress/index";
解决跳转页面的问题

5)、调整 standalone配置信息,开启或关闭单机工作模式

ps:目前项目代码默认启动standalone模式,不需要依赖任何服务端和存储,能够简单快速的实现单机的录制回放,控制单机模式的开关在~/.sandbox-module/cfg/repeater.properties 文件中的 repeat.standalone.mode=true //开启或关闭单机工作模式,关闭单机模式后,配置拉取/消息投递等都依赖repeater.properties中配置的具体url,例如使用repeater-console界面中设置的配置信息;如不想通过http拉取和消息投递的也可以自己实现BroadcasterConfigManager。

配置路径:jvm-sandbox-repeater/bin/repeater.properties。如下,主要配置中的ip和端口号。配置要求:如果你是本机器则配置成127.0.0.1或lcoalhost,如果是远程主机部署,则配置成repeater-console服务器IP端口

ps:repeat.standalone.mode必须改成false(关闭单机工作模式)。

位置:jvm-sandbox-repeater/bin/repeater.properties 如果你是本机器则配置成127.0.0.1或lcoalhost,如果是远程主机部署,则配置成repeater-console服务器IP端口 # 录制消息投递地址 broadcaster.record.url=http://127.0.0.1:8001/facade/api/record/save # 回放结果投递地址 broadcaster.repeat.url=http://127.0.0.1:8001/facade/api/repeat/save # 回放消息取数据地址 repeat.record.url=http://127.0.0.1:8001/facade/api/record/%s/%s # 配置文件拉取地址 repeat.config.url=http://127.0.0.1:8001/facade/api/config/%s/%s # 心跳上报配置 repeat.heartbeat.url=http://127.0.0.1:8001/module/report.json # 是否开启脱机工作模式 repeat.standalone.mode=false # 是否开启spring advice拦截 repeat.spring.advice.switch=false

6)、修改日志存放脚本

脚本位置:jvm-sandbox-repeater/bin/repeater-logback.xml

ps:红色部分根据实际情况配置

存放位置:/jvm-sandbox-repeater/bin/repeater-logback.xml

<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="10000">

<appender name="REPEATER-FILE-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/data/fll/logs/sandbox/repeater/repeater.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>/data/fll/logs/sandbox/repeater/repeater.log.%d{yyyy-MM-dd}</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>

<root level="info">
<appender-ref ref="REPEATER-FILE-APPENDER"/>
</root>

</configuration>

7)、 修改install-local.sh安装脚本(此脚本用于安装sandbox 和sandbox-repeater)

脚本位置:jvm-sandbox-repeater/bin/install-local.sh

ps:红色部分根据实际情况配置

#!/usr/bin/env bash

# repeater's target dir
REPEATER_TARGET_DIR=../target/repeater

typeset HOME=/data/fll
typeset SANDBOX_HOME=/data/fll/sandbox

# exit shell with err_code
# $1 : err_code
# $2 : err_msg
exit_on_err()
{
[[ ! -z "${2}" ]] && echo "${2}" 1>&2
exit ${1}
}

# package
#sh ./package.sh || exit_on_err 1 "install failed cause package failed"

# extract sandbox to ${HOME}
curl -s http://sandbox-ecological.oss-cn-hangzhou.aliyuncs.com/sandbox-1.2.1-bin.tar | tar xz -C ${HOME} || exit_on_err 1 "extract sandbox failed"

# copy module to ~/.sandbox-module

#mkdir -p ${SANDBOX_HOME}/.sandbox-module || exit_on_err 1 "permission denied, can not mkdir ~/.sandbox-module"
cp -r ${REPEATER_TARGET_DIR}/* ${SANDBOX_HOME}/sandbox-module || exit_on_err 1 "permission denied, can not copy module to ~/.sandbox-module"

 

2、安装sandbox 和repeater(通过编译和打包源码进行安装)

1) 源码安装:进入~/xxx/jvm-sandbox-repeater/目录下,执行install-local.sh安装脚本(此脚本用于安装sandbox 和sandbox-repeater)

[root@yog bin]# ./install-local.sh 

1.2.2 通过官方用户手册进行安装sandbox和repeater

ps:如果只是想简单运行,可以直接使用官方版本,参考官方用户手册,以standalone模式把玩。

1、修改install-repeater.sh安装脚本(此脚本是通过官网提供jar包进行安装)

脚本位置:jvm-sandbox-repeater/bin/install-repeater.sh

ps:红色部分根据实际情况配置

#!/usr/bin/env bash

#typeset SANDBOX_HOME=${HOME}/sandbox
echo ${HOME}

typeset HOME=/data/fll
typeset MODULE_HOME=/data/fll/sandbox/sandbox-module

# exit shell with err_code
# $1 : err_code
# $2 : err_msg
exit_on_err()
{
[[ ! -z "${2}" ]] && echo "${2}" 1>&2
exit ${1}
}

main(){
echo "====== begin to install sandbox and repeater module ======";
echo "====== step 0 begin to download sandbox package ======";
curl -s http://sandbox-ecological.oss-cn-hangzhou.aliyuncs.com/sandbox-1.2.1-bin.tar | tar xz -C ${HOME} || exit_on_err 1 "extract sandbox failed"
echo "====== step 1 begin to download repeater module package ======";
if [ ! -d ${MODULE_HOME} ]; then
mkdir -p ${MODULE_HOME} || exit_on_err 1 "permission denied mkdir ${MODULE_HOME}"
fi
curl -s http://sandbox-ecological.oss-cn-hangzhou.aliyuncs.com/repeater-stable-bin.tar | tar x -C ${MODULE_HOME} || exit_on_err 1 "extract repeater failed"
echo "====== install finished ======";
}

main

ps:安装andbox 和 repeater后,对~/sandbox/sandbox-module/repeater-bootstrap.jar按照上面配信信息进行修改对应文件。

启动篇

一、下载和打包被监测应用demo

1、下载和打包被监测应用demo

1)、下载被监测应用demo:

git clone GitHub - chenhengjie123/gs-rest-service: Building a RESTful Web Service :: Learn how to create a RESTful web service with Spring.

2)、打包被监测应用demo:

# 在示例项目 clone 后的根目录中运行
cd complete 
# demo打成jar包
mvn install

打包成功后,被监测应用demo目录结构:

二、启动 repeater-console

1. 方法有三:

  1. 【本地试用强烈推荐】idea 右键运行启动:jvm-sandbox-repeater/repeater-console/repeater-console-start/src/main/java/com/alibaba/repeater/console/start/Application.java
  2. 打成 jar 包运行,项目根目录路径下执行以下命令。

    # 在 repeater 项目根目录进行

    mvn install -DskipTests && java -jar repeater-console/repeater-console-start/target/*.jar

  3. 从安装好的repeater中启动console
    进入~/sandbox/sandbox-module目录下,运行repeater-bootstrap.jar包

#位置:/data/fll/sandbox/sandbox-module ps:红色部分是自己存放配置

java -jar repeater-bootstrap.jar

启动成功,应该出现类似下面的日志:

...
2021-08-30 11:53:15.105 INFO 2892 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 4000 (http)
2021-08-30 11:53:15.109 INFO 2892 --- [ main] c.a.repeater.console.start.Application : Started Application in 7.507 seconds (JVM running for 8.427)

2、验证repeater-console启动成功

打开此 url 即可打开 repeater-console 的界面:http://127.0.0.1:8001/regress/index.htm

三、repeater以agent模式注入到被测应用并进行录制回放

现在,借助界面来做一次录制回放吧

1)、在 console 增加配置,用于对接应用
2)、让 repeater 注入到被测应用,上报数据到 console
3)、在 console 中操作,进行录制和回放

接下来,一步一步操作。

1 :在 console 增加配置,用于对接应用

访问地址:http://127.0.0.1:4000/regress/index.htm

点击左侧的 【配置管理】,添加如下配置:

应用名:repeater(自定义应用名)

环境:daily(自定义环境名)

配置信息

{
  "useTtl" : true,
  "degrade" : false,
  "exceptionThreshold" : 1000,
  "sampleRate" : 10000,
  "pluginsPath" : null,
  "httpEntrancePatterns" : [ "^/greeting.*$" ],
  "javaEntranceBehaviors" : [ {
    "classPattern" : "hello.GreetingController",
    "methodPatterns" : [ "greeting" ],
    "includeSubClasses" : false
  } ],
  "javaSubInvokeBehaviors" : [],
  "pluginIdentities" : [ "http", "java-entrance", "java-subInvoke", "mybatis", "ibatis" ],
  "repeatIdentities" : [ "java", "http" ]
}

点击【保存】,存下配置

2 : repeater 注入被监测应用程序(采用agent模式)

ps:此处被监测应用是以上文gs-rest-service的demo为例

1)agent模式启动与关闭

agent 模式下的启停都跟随应用,配置好参数后,应用启动则启动,应用停止则停止。

注意事项:

1) sandbox-agent.jar :自己安装的位置进行配置

2)录制应用名、录制环境 :与console配置管理中的一致

3)repeater启动端口 :未在进程中使用过的

4)application.jar:被测应用

java

-javaagent:${HOME}/sandbox/lib/sandbox-agent.jar=server.port=${repeater启动端口}\;server.ip=0.0.0.0 \

-Dapp.name=${录制应用名} \

-Dapp.env=${录制环境} \

-jar application.jar

执行demo启动命令脚本:

java -javaagent:/data/fll/sandbox/lib/sandbox-agent.jar=server.port=12580\;server.ip=0.0.0.0 \
-Dapp.name=repeater \
-Dapp.env=daily \
-jar I:/fll_code_example/gs-rest-service/complete/target/gs-rest-service-0.1.0.jar

注意:

红色部分是自己的文件目录

蓝色修改成console配置信息中参数

2)进入被监测项目,检查项目是否启动成功

启动成功检查方法:

  1. 应用正常启动,无报错

2021-08-30 14:10:33.143 INFO 2656 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2021-08-30 14:10:33.359 INFO 2656 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 4000 (http) with context path ''
2021-08-30 14:10:33.362 INFO 2656 --- [ main] hello.Application : Started Application in 2.777 seconds (JVM running for 4.069)

      2. 进入 console 的【在线模块】,应该能看到增加了当前这个被测应用的心跳记录:

      3. 看日志,日志路径~/logs/sandbox/repeater/repeater.log。

需要关注的日志内容主要是是以下几种:

  • 以 enable plugin开头的,查看插件挂载情况
  • register event bus success in repeat-register,说明插件加载完成,模块加载完成,可以开始录制和回放的行为。

PS:其中会夹杂很多以Register bean:name=的日志,这些日志说明了被 repeater 记录下来的运行在应用 jvm 中的实例,会在 java 回放的时候用到。但是与启动 repeater 关系不大,在启动阶段可忽略。

2021-08-30 14:10:33 INFO initializing logback success. file=/Users/elesgong/.sandbox-module/cfg/repeater-logback.xml;

2021-08-30 14:10:33 INFO module on loaded,id=repeater,version=1.0.0,mode=AGENT
2021-08-30 14:10:33 INFO agent launch mode,use Spring Instantiate Advice to register bean.
2021-08-30 14:10:33 INFO onActive
2021-08-30 14:10:33 INFO pull repeater config success,config=com.alibaba.jvm.sandbox.repeater.plugin.domain.RepeaterConfig@56996122
2021-08-30 14:10:33 INFO http plugin required servlet-api class router,waiting for class loading
2021-08-30 14:10:33 INFO http plugin required servlet-api class router,waiting for class loading
2021-08-30 14:10:33 INFO enable plugin mybatis success
2021-08-30 14:10:33 INFO add watcher success,type=mybatis,watcherId=1003
2021-08-30 14:10:33 INFO enable plugin redis success
2021-08-30 14:10:33 INFO add watcher success,type=redis,watcherId=1005
2021-08-30 14:10:33 INFO add watcher success,type=redis,watcherId=1007
2021-08-30 14:10:33 INFO enable plugin http success
2021-08-30 14:10:33 INFO add watcher success,type=http,watcherId=1009
2021-08-30 14:10:33 INFO enable plugin java-entrance success
2021-08-30 14:10:33 INFO watch plugin occurred error
com.alibaba.jvm.sandbox.repeater.plugin.exception.PluginLifeCycleException: enhance models is empty, plugin type is java-entrance
at com.alibaba.jvm.sandbox.repeater.plugin.core.impl.AbstractInvokePluginAdapter.watchIfNecessary(AbstractInvokePluginAdapter.java:122)
at com.alibaba.jvm.sandbox.repeater.plugin.core.impl.AbstractInvokePluginAdapter.watch(AbstractInvokePluginAdapter.java:65)
at com.alibaba.jvm.sandbox.repeater.module.RepeaterModule.initialize(RepeaterModule.java:187)
at com.alibaba.jvm.sandbox.repeater.module.RepeaterModule.access$500(RepeaterModule.java:61)
at com.alibaba.jvm.sandbox.repeater.module.RepeaterModule$1.run(RepeaterModule.java:133)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
2021-08-30 14:10:33 INFO enable plugin java-subInvoke success
2021-08-30 14:10:33 INFO add watcher success,type=java,watcherId=1011
2021-08-30 14:10:33 INFO add watcher success,type=java,watcherId=1013
2021-08-30 14:10:33 INFO add watcher success,type=java,watcherId=1019
2021-08-30 14:10:34 INFO register event bus success in repeat-register

 3 :开始录制,给这个被测应用输送一些流量

录制接口分2种方法:

1) 命令请求

# 手动发出2条请求
$ curl -s 'http://localhost:8080/greeting'
{"id":1,"content":"Hello, World!"}%
$ curl -s 'http://localhost:8080/greeting?name=User'
{"id":2,"content":"Hello, User!"}%

2)postman请求

3)查看录制结果:点击console 的【在线流量】,能看到刚发出的两条请求已经录制下来了: 

4 :回放请求。直接点击第一行末尾的回放按钮,进行回放:

然后,就可以看到回放结果了。稍等几秒后刷新下回放结果界面,就能看到执行结果

 由于被测应用实际上 id 自增逻辑没有依赖任何外部服务,每次请求都会自动 +1 ,所以回放记录是失败的。

附加

repeater以attach模式注入到被测应用

步骤如下:

1 :下载和打包被监测应用demo

1)、下载被监测应用demo:

git clone GitHub - chenhengjie123/gs-rest-service: Building a RESTful Web Service :: Learn how to create a RESTful web service with Spring.

2)、启动被监测应用

# 在示例项目 clone 后的根目录中运行
cd complete 
# 启动demo
mvn install && java -jar target/*.jar

2 :启动repeater-console服务

1:【本地试用强烈推荐】idea 右键运行启动:jvm-sandbox-repeater/repeater-console/repeater-console-start/src/main/java/com/alibaba/repeater/console/start/Application.java

# 在 repeater 项目根目录进行

mvn install -DskipTests && java -jar repeater-console/repeater-console-start/target/*.jar

启动成功后,应有类似如下日志:

...
2021-08-30 17:30:45.949  INFO 32158 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 4000 (http) with context path ''
2021-08-30 17:30:45.952  INFO 32158 --- [           main] hello.Application                        : Started Application in 2.062 seconds (JVM running for 2.448)

2 :在 console 增加配置,用于对接应用

ps:此处配置应用名和环境与agent模式不一样,不可自定义应用名和环境

点击左侧的 【配置管理】,添加如下配置:

应用名:unknown
环境:unknown
配置信息

{
  "useTtl" : true,
  "degrade" : false,
  "exceptionThreshold" : 1000,
  "sampleRate" : 10000,
  "pluginsPath" : null,
  "httpEntrancePatterns" : [ "^/greeting.*$" ],
  "javaEntranceBehaviors" : [ {
    "classPattern" : "hello.GreetingController",
    "methodPatterns" : [ "greeting" ],
    "includeSubClasses" : false
  } ],
  "javaSubInvokeBehaviors" : [],
  "pluginIdentities" : [ "http", "java-entrance", "java-subInvoke", "mybatis", "ibatis" ],
  "repeatIdentities" : [ "java", "http" ]
}

点击【保存】,存下配置

3:让 repeater 以attach模式注入到被测应用

1)attach 模式启动与关闭

切换至被录制应用启动用户,执行以下启动命令。注意 repeater 启动端口需要选取一个没有被占用的端口。attach 模式下,录制应用名和录制环境这两个参数都会被默认为unknown

# 启动命令

~/sandbox/bin/sandbox.sh -p ${被录制应用进程号} -P ${repeater启动端口}

# 关闭命令 ~/sandbox/bin/sandbox.sh -S ${被录制应用进程号}

注意:

被录制应用进程号:被录制应用进程号

repeater启动端口:进程中未使用端口号

repeater 启动命令:

sh /data/fll/sandbox/bin/sandbox.sh -p `ps -ef | grep "target/gs-rest-service-0.1.0.jar" | grep -v grep | awk '{print $2}'` -P 12580

ps:红色部分代码自己安装的sandbox位置

repeater 关闭命令:

sh /data/fll/sandbox/bin/sandbox.sh -S -p 'ps -ef | grep "target/gs-rest-service-0.1.0.jar" | grep -v grep | awk '{print $2}'' -P 12580

ps:红色部分代码自己安装的sandbox位置

启动成功/关闭成功的结果:(查看repeater日志,日志位置在xxxxx/jvm-sandbox-repeater/bin/repeater-logback.xml 中配置路径)

ps:然后进入 console 的【在线模块】,应该能看到增加了当前这个被测应用的心跳记录:

4 :开始录制。给这个被测应用输送一些流量

录制接口分2种方法:

1) 命令请求

# 手动发出2条请求
$ curl -s 'http://localhost:8080/greeting'
{"id":1,"content":"Hello, World!"}%
$ curl -s 'http://localhost:8080/greeting?name=User'
{"id":2,"content":"Hello, User!"}%

 2)postman请求

然后打开 console 的【在线流量】,能看到刚发出的两条请求已经录制下来了: 

5 :回放请求。直接点击第一行末尾的回放按钮,进行回放:

然后,就可以看到回放结果了。稍等几秒后刷新下回放结果界面,就能看到执行结果

由于被测应用实际上 id 自增逻辑没有依赖任何外部服务,每次请求都会自动 +1 ,所以回放记录是失败的。

repeater启动模式分析篇

attach 和 agent 启动模式对比

模式优点不足
attach1. 不需要启停应用,即插即用,随时停止
2. 更新配置不需要重启应用
1. 进行 java 回放的时候可能由于无法获取到对应实例而回放失败
2. 如果需要对 repeater 进行 debug,需要将 repeater 代码嵌入到被录制应用的代码中,不方便 debug
3. 不可进行录制应用名和录制环境的配置,会被默认标记为 unknown
agent1. 进行 java 回放的时候能够获取到对应实例能够正常回放
2. 启动应用时开启调试,即可远程调试 repeater
3. 支持配置录制应用名以及录制环境,方便在录制记录中进行区分
1. 启动/停止都需要重启应用
2. 更新配置也需要重启应用

附录篇

一、过程中的报错及解决

1、注入 repeater 到被测应用后,console 报错:

2021-08-30 17:30:28.822 ERROR 39333 --- [nio-8001-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
    at com.alibaba.repeater.console.start.controller.api.ConfigFacadeApi.getConfig(ConfigFacadeApi.java:34) ~[classes!/:na]
    at sun.reflect.GeneratedMethodAccessor77.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]

原因:上报心跳包后,appName 和 environment 和配置对不上。
解决:请确认有至少一个配置,appName 和 environment 都是 unknown

2、报错 org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource ‘/blocks/pager.vm’] with root cause ,且界面打不开

原因:没有按照前面所述修改 console 源码,导致引用其他模板的部分根目录不正确。
解决:按照前面描述,把 #parse("/blocks ,统一改替换为 #parse("blocks 即可)。

本文转载自: 通用流量录制回放工具 jvm-sandbox-repeater 尝鲜 (四)——新版带界面 console 的使用 · TesterHome通用流量录制回放工具 jvm-sandbox-repeater 尝鲜 (四)——新版带界面 console 的使用 – 贝克街的捉虫师, 感谢原作者的无私分享。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值