jvm-sandbox-repeater 精简版部署之standalone模式

2023-12-14 20:31:10

jvm-sandbox-repeater?仅仅提供了录制回放的能力,如果需要完成业务回归实时监控压测等平台,后面须要有一个数据中心负责采集数据的加工、存储、搜索,repeater-console提供了简单的demo示例;一个模块管理平台负责管理JVM-Sandbox各模块生命周期;一个配置管理平台负责维护和推送jvm-sandbox-repeater采集所须要的各种配置变更

在阿里集团淘系技术质量内部,已有一套完整的体系在持续运行,从17年开始支持了淘系技术质量部的CI、建站、系统重构等多方面质量保障任务,后续如有需要也会考虑把更多的东西开源回馈社区

注意:目前项目代码默认启动standalone模式,不需要依赖任何服务端和存储,能够简单快速的实现单机的录制回放, 控制单机模式的开关在~/.sandbox-module/cfg/repeater.properties?配置文件的?repeat.standalone.mode=true,开启或关闭单机工作模式,关闭单机模式后,配置拉取/消息投递等都依赖repeater.properties中配置的具体url;如不想通过http拉取和消息投递的也可以自己实现BroadcasterConfigManager。稍后我们会公布一份录制回放所需的完整架构图以及jvm-sandbox-repeater在整个体系中的位置供大家工程使用做参考。

?编译源码部署:

?代码结构

[root@k8s-worker27-65 jvm-sandbox-repeater]# ls
bin   hessian-lite  pom.xml    repeater-aide    repeater-console  repeater-plugin-api   repeater-plugins  travis.sh
docs  LICENSE       Readme.md  repeater-client  repeater-module   repeater-plugin-core  target
[root@k8s-worker27-65 jvm-sandbox-repeater]# ls bin/
bootstrap.sh  install-local.sh     package.sh            repeater-logback.xml  sandbox-1.3.3-bin.tar
health.sh     install-repeater.sh  repeater-config.json  repeater.properties

?standalone模式,repeat.standalone.mode=true

[root@k8s-worker27-65 jvm-sandbox-repeater]# git cloen https://github.com/alibaba/jvm-sandbox-repeater.git

[root@k8s-worker27-65 jvm-sandbox-repeater]# pwd
/root/work/traffic/jvm-sandbox-repeater
[root@k8s-worker27-65 jvm-sandbox-repeater]# cat bin/repeater.properties 
# 录制消息投递地址
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=true

# 是否开启spring advice拦截
repeat.spring.advice.switch=false;

由于https://github.com/alibaba/jvm-sandbox-repeater/releases/download/v1.0.0/sandbox-1.3.3-bin.tar?下载费劲,我先现在了然后改成一下脚本不用每次下载

[root@k8s-worker27-65 jvm-sandbox-repeater]# cat bin/install-local.sh 
#!/usr/bin/env bash

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

# 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 https://github.com/alibaba/jvm-sandbox-repeater/releases/download/v1.0.0/sandbox-1.3.3-bin.tar | tar xz -C ${HOME} || exit_on_err 1 "extract sandbox failed"
cat sandbox-1.3.3-bin.tar | tar xz -C ${HOME} || exit_on_err 1 "extract sandbox failed"

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

快速开始

1. 本地standalone工作(剥离服务端和存储,本机实现录制/回放)

step0 安装sandbox/启动bootstrap
[root@k8s-worker27-65 jvm-sandbox-repeater]# cd bin
[root@k8s-worker27-65 jvm-sandbox-repeater]# ./bootstrap.sh

安装后的结构:

[root@k8s-worker27-65 .sandbox-module]# ls /root/sandbox/
bin  cfg  example  install-local.sh  lib  module  provider  sandbox-module
[root@k8s-worker27-65 .sandbox-module]# ls /root/.sandbox-module/
cfg  plugins  repeater-bootstrap.jar  repeater-module.jar

启动命令:也可以自己手动启动

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -javaagent:/root/sandbox/lib/sandbox-agent.jar=server.port=8820\;server.ip=0.0.0.0 -Dapp.name=jettopro -Dapp.env=sit  -jar  /root/.sandbox-module/repeater-bootstrap.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

正常启动的是这个应用程序:?

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000  -jar  /root/.sandbox-module/repeater-bootstrap.jar

录播:

[root@k8s-worker27-65 ~]# curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId=127000000001156034386424510000ed'
<h1 align="center" style="color:red;margin-top:300px">JAVA是世界上最好的语言!</h1>

回放

curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId-X=127000000001156034386424510000ed'
<h1 align="center" style="color:red;margin-top:300px">Python是世界上最好的语言!</h1>

?此时回放是有问题的,因为没有监听自己的repeater-bootstrap.jar这个应用,监听方式有两种方

1.javaagent方式

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -javaagent:/root/sandbox/lib/sandbox-agent.jar=server.port=8820\;server.ip=0.0.0.0 -Dapp.name=jettopro -Dapp.env=sit  -jar  /root/.sandbox-module/repeater-bootstrap.jar

2.attach方式,先获取pid然后监听

[root@k8s-worker27-65 ~]# ps -ef |grep java
root     16713 13435 99 10:55 pts/1    00:00:33 java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -jar /root/.sandbox-module/repeater-bootstrap.jar

?监听:

[root@k8s-worker27-65 ~]# cd ~/sandbox/bin/
[root@k8s-worker27-65 bin]# ls
sandbox.sh
[root@k8s-worker27-65 bin]# ./sandbox.sh -p 16713 -P 12580
cat: /root/.sandbox.token: 没有那个文件或目录
                    NAMESPACE : default
                      VERSION : 1.3.3
                         MODE : ATTACH
                  SERVER_ADDR : 0.0.0.0
                  SERVER_PORT : 12580
               UNSAFE_SUPPORT : ENABLE
                 SANDBOX_HOME : /root/sandbox/bin/..
            SYSTEM_MODULE_LIB : /root/sandbox/bin/../module
              USER_MODULE_LIB : /root/sandbox/sandbox-module;~/.sandbox-module;
          SYSTEM_PROVIDER_LIB : /root/sandbox/bin/../provider
           EVENT_POOL_SUPPORT : DISABLE

?然后就是可以开始录制和回放了

step1 开始录制

[root@k8s-worker27-65 ~]# curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId=127000000001156034386424510000ed'
<h1 align="center" style="color:red;margin-top:300px">C#是世界上最好的语言!</h1>[root@k8s-worker27-65 ~]# curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId=127000000001156034386424510000ed'
<h1 align="center" style="color:red;margin-top:300px">C++是世界上最好的语言!</h1>[root@k8s-worker27-65 ~]#

是不是看到了C++是世界上最好的语言;我们希望让这一刻永远定格;访问链接时,repeater插件通过Repeat-TraceId=127000000001156034386424510000ed,唯一追踪到了这一次请求,后台服务返回了C++是世界上最好的语言!,repeater把画面定格在了这一秒并将结果和127000000001156034386424510000ed绑定

step2 开始回放
[root@k8s-worker27-65 ~]# curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId-X=127000000001156034386424510000ed'
<h1 align="center" style="color:red;margin-top:300px">C++是世界上最好的语言!</h1>[root@k8s-worker27-65 ~]# curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId-X=127000000001156034386424510000ed'
<h1 align="center" style="color:red;margin-top:300px">C++是世界上最好的语言!</h1>[root@k8s-worker27-65 ~]# curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId-X=127000000001156034386424510000ed'
<h1 align="center" style="color:red;margin-top:300px">C++是世界上最好的语言!</h1>[root@k8s-worker27-65 ~]#

无论我们多少次访问这个地址,都将返回Repeat-TraceId=127000000001156034386424510000ed绑定的录制信息C++是世界上最好的语言!;如果重新访后又会将最新的返回结果绑定到Repeat-TraceId=127000000001156034386424510000ed(为了快速演示,将链路追踪的标志提到参数中进行透传了)

RegressController中提供了更多的测试用例,包括异步servlet、多线程调用、复杂结构返回对象,可以根据slogan类似的方式进行测试。

简单揭秘:/regress/slogan接口调用了RegressServiceImpl#slogan方法

private AtomicInteger sequence = new AtomicInteger(0);

private String[] slogans = new String[]{"JAVA", "Python", "PHP", "C#", "C++", "Javascript", "GO"};

public String slogan() {
    return slogans[sequence.getAndIncrement() % slogans.length] + "是世界上最好的语言!";
}

仔细查看该方法代码会发现,每次请求时都会返回不同的语言,为什么回放时每次都返回同样的结果呢?原因很简单,我们对RegressServiceImpl#slogan进行了mock,在回放时开启了mock能力,调用slogan的BEFORE事件时找到了合适值,直接利用ProcessControlException.throwReturnImmediately进行了直接返回,RegressServiceImpl的第72行代码在mock回放时永远不会走到。得益于在repeater-config.json中开启了java插件并且默认拦截了RegressServiceImpl#slogan方法,录制slogan时同时录制java子调用

想要知道应用层面发生了什么吗?请看《Slogan Demo究竟发生了什么

?不编译非源码部署:

[root@k8s-worker27-65 bin]# ls sandbox-1.3.3-bin.tar repeater-stable-bin.tar 
repeater-stable-bin.tar  sandbox-1.3.3-bin.tar

1. sandbox-1.3.3-bin.tar:https://github.com/alibaba/jvm-sandbox-repeater/releases/download/v1.0.0/sandbox-1.3.3-bin.tar

1.1)这个是官网下载的解压后:

[root@k8s-worker27-65 ~]# ls sandbox
bin  cfg  example  install-local.sh  lib  module  provider  sandbox-module

1.2 )配置文件:

[root@k8s-worker27-65 sandbox]# cat cfg/sandbox.properties  |grep -v "#" |grep -v "^$"
user_module=/root/sandbox-module;
server.charset=UTF-8
unsafe.enable=true

user_module=/root/sandbox-module;? 配置为sandbox-module所在的路径即可

2.?repeater-stable-bin.tar 自己编译或官网下载都可以?

https://github.com/alibaba/jvm-sandbox-repeater/releases/download/v1.0.0/repeater-stable-bin.tar

2.1)解压之后:

[root@k8s-worker27-65 ~]# ls sandbox-module/
cfg  plugins  repeater-bootstrap.jar  repeater-data  repeater-module.jar

2.2)配置文件:

[root@k8s-worker27-65 cfg]# cat repeater.properties  |grep -v "#" |grep -v "^$"
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=true
repeat.spring.advice.switch=false;

repeat.standalone.mode=true?
【1】true:就是本地模式不需要数据库存在录播文件,在本地目录中存储[root@k8s-worker27-65 sandbox-module]# ls sandbox-module/repeater-data/record/127000000001156034386424510000ed

【2】false:需要数据库mysql进行存储

录制自己的应用:

[root@k8s-worker27-65 aaaa]# cat repeater/cfg/repeater-config.json
{
  "useTtl" : true,
  "degrade" : false,
  "exceptionThreshold" : 1000,
  "sampleRate" : 10000,
  "pluginsPath" : null,
  "httpEntrancePatterns" : [ "^/greeting.*$" ],
  "javaEntranceBehaviors" : [],
  "javaSubInvokeBehaviors" : [ {
    "classPattern" : "hello.GreetingController",
    "methodPatterns" : [ "greeting" ],
    "includeSubClasses" : false
  } ],
  "pluginIdentities" : [ "http", "java-entrance", "java-subInvoke", "mybatis", "ibatis" ],
  "repeatIdentities" : [ "java", "http" ]
}

自己应用的pid:26362?

[root@k8s-worker27-65 target]# ps -ef |grep java
root     26200 13435 11 14:20 pts/1    00:01:00 java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -javaagent:/opt/aaaa/sandbox/lib/sandbox-agent.jar=server.port=8820;server.ip=0.0.0.0 -Dapp.name=jettopro -Dapp.env=sit -jar /opt/aaaa/repeater/repeater-bootstrap.jar
root     26362 13398  5 14:21 pts/0    00:00:22 java -jar gs-rest-service-0.1.0.jar

1)attach自己的pid进行监听

[root@k8s-worker27-65 bin]# pwd
/opt/aaaa/sandbox/bin
[root@k8s-worker27-65 bin]# ./sandbox.sh -p 26362 -P 12501
                    NAMESPACE : default
                      VERSION : 1.3.3
                         MODE : ATTACH
                  SERVER_ADDR : 0.0.0.0
                  SERVER_PORT : 12501
               UNSAFE_SUPPORT : ENABLE
                 SANDBOX_HOME : /opt/aaaa/sandbox/bin/..
            SYSTEM_MODULE_LIB : /opt/aaaa/sandbox/bin/../module
              USER_MODULE_LIB : /opt/aaaa/sandbox/sandbox-module;/opt/aaaa/repeater;
          SYSTEM_PROVIDER_LIB : /opt/aaaa/sandbox/bin/../provider
           EVENT_POOL_SUPPORT : DISABLE

2)测试自己的服务是否可以录制:因为是录制id一直在增加

[root@k8s-worker27-65 repeater]# pwd
/opt/aaaa/repeater
[root@k8s-worker27-65 repeater]# ls
cfg  plugins  repeater-bootstrap.jar  repeater-module.jar
[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId=127000000001156034386424510000ea'
{"id":25,"content":"Hello, jettech01!"}[root@k8s-worker27-65 repeater]# 
[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId=127000000001156034386424510000eb'
{"id":26,"content":"Hello, jettech01!"}[root@k8s-worker27-65 repeater]# 
[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId=127000000001156034386424510000ec'
{"id":27,"content":"Hello, jettech01!"}[root@k8s-worker27-65 repeater]# 
[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId=127000000001156034386424510000ed'
{"id":28,"content":"Hello, jettech01!"}[root@k8s-worker27-65 repeater]# 
[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId=127000000001156034386424510000ee'
{"id":29,"content":"Hello, jettech01!"}[root@k8s-worker27-65 repeater]#
[root@k8s-worker27-65 repeater]# ls
cfg  plugins  repeater-bootstrap.jar  repeater-data  repeater-module.jar



有这个 repeater-data 目录说明录制成功

回放:多次执行一直都是id为25没有增加,说明定在了id为25这个条目上,可以对id=25进行多次回放,也可以选在id进行回放。但是id没有进行录制过的进行回放是回放不了的如id是30的

[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId-X=127000000001156034386424510000ea'
{"id":25,"content":"Hello, jettech01!"}[root@k8s-worker27-65 repeater]# 
[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId-X=127000000001156034386424510000eb'
{"id":26,"content":"Hello, jettech01!"}
[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId-X=127000000001156034386424510000ec'
{"id":27,"content":"Hello, jettech01!"}[root@k8s-worker27-65 repeater]# 
[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId-X=127000000001156034386424510000ed'
{"id":28,"content":"Hello, jettech01!"}[root@k8s-worker27-65 repeater]# 
[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId-X=127000000001156034386424510000ee'
{"id":29,"content":"Hello, jettech01!"}[root@k8s-worker27-65 repeater]# 
[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId-X=127000000001156034386424510000ef'
{"id":30,"content":"Hello, jettech01!"}[root@k8s-worker27-65 repeater]# 
[root@k8s-worker27-65 repeater]# curl -s 'http://localhost:8080/greeting?name=jettech01&Repeat-TraceId-X=127000000001156034386424510000ea'
{"id":25,"content":"Hello, jettech01!"}[root@k8s-worker27-65 repeater]# 

https://github.com/alibaba/jvm-sandbox-repeater/blob/master/docs/user-guide-cn.md#2-%E5%BF%AB%E9%80%9F%E5%BD%95%E5%88%B6%E8%87%AA%E5%B7%B1%E5%BA%94%E7%94%A8

文章来源:https://blog.csdn.net/Michaelwubo/article/details/134848903
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。