接口测试 通用流量录制回放工具 jvm-sandbox-repeater 尝鲜记录 (0716 跑通基于 console 的录制回放)

陈恒捷 for PPmoney · 2019年07月07日 · 最后由 陈恒捷 回复于 2021年01月08日 · 23 次阅读
本帖已被设为精华帖!

背景

流量录制回放近几年已经越来越火。如阿里开放的 doom 、滴滴开源的 RDebug 。而公司随着业务的快速发展,回归测试的耗时越来越长,而且可以留给脚本维护的时间也并不多。因此也期望通过流量录制回放,提高回归测试的效率。

而刚好前几天看到阿里技术公众号推送的一篇 jvm-sandbox 的文章,里面有提到开源了其中做流量录制回放的 repeater 模块,所以尝鲜一下。

为了方便记录和阅读,目前已经调整为系列文章。导航地址如下:

通用流量录制回放工具 jvm-sandbox-repeater 尝鲜记录(本文)
通用流量录制回放工具 jvm-sandbox-repeater 尝鲜 (二)——repeater-console 使用
通用流量录制回放工具 jvm-sandbox-repeater 尝鲜 (三)—— repeater plugin 开发

jvm-sandbox-repeater 简介

直接搬运官方文档里面的介绍吧

image_1df2dcu799j9pif16k3kje1s1j9.png-187.1kB
image_1df2ddd0jf2sk7rvjlqkduavm.png-61.8kB

github 地址:https://github.com/alibaba/jvm-sandbox-repeater

简单的说,就是一个可以在不修改程序的情况下,进行一个服务 http、java、dubbo 入参及返回值的录制。也支持快速扩展 api ,实现自己的插件。

standalone 快速开始

step0 安装 sandbox/启动 bootstrap

cd bin
./bootstrap.sh

等待 SpringBoot 应用启动完成 -> Started Application in 4.797 seconds (JVM running for 6.586)

step1 开始录制

curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId=127000000001156034386424510000ed'

执行结果如下:

访问链接时,repeater 插件通过 Repeat-TraceId=127000000001156034386424510000ed,唯一追踪到了这一次请求,后台服务返回了JAVA是世界上最好的语言!,repeater 把画面定格在了这一秒并将结果和 firstId 绑定

step2 开始回放

curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId-X=127000000001156034386424510000ed'

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

完整执行结果如下:

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

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

光是执行官方用例,当然不能满足我们需要啦。我们来测试下,如果有多个 Repeat-TraceId ,是否可以分别录制?

测试一下:

# 录制一个 128 开头的 traceId ,返回结果是 java
➜  bin git:(master) curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId=128000000001156034386424510000ed'
<h1 align="center" style="color:red;margin-top:300px">JAVA是世界上最好的语言!</h1>%                                                                           
# 录制一个 129 开头的 traceId ,返回结果是 Python
➜  bin git:(master) curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId=129000000001156034386424510000ed'
<h1 align="center" style="color:red;margin-top:300px">Python是世界上最好的语言!</h1>%                                                                         
# 回放前面 128 的流量
➜  bin git:(master) curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId-X=128000000001156034386424510000ed'
<h1 align="center" style="color:red;margin-top:300px">JAVA是世界上最好的语言!</h1>%                                                                           
# 回放前面 129 的流量
➜  bin git:(master) curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId-X=129000000001156034386424510000ed'
<h1 align="center" style="color:red;margin-top:300px">Python是世界上最好的语言!</h1>%  

看来确实是有效的。

录制目标服务

前面只是个简单的练手,实际用不用得了,当然的实际项目说话啦。

为了简单,此处使用了几个 spring boot 的示例项目当做实际项目使用。

  • restful-api

项目地址:https://github.com/chenhengjie123/gs-rest-service(官方文档:https://spring.io/guides/gs/rest-service/ ,在官方的基础上增加了请求日志打印的功能,便于查看回放效果)

clone 后,直接用 complete 里面的完整示例,当做被测程序。

程序本身功能:当请求 http://localhost:8080/greeting?name=User 时,返回 {"id":2,"content":"Hello, User!"} 。其中 Hello 后面的名称根据请求参数的 name 自动替换,id 会自动递增。

接下来,按照官方的说明,进行操作:

step0 安装 sandbox 和插件到应用服务器

curl -s http://sandbox-ecological.oss-cn-hangzhou.aliyuncs.com/install-repeater.sh | sh

正常日志输出:

======  begin to install sandbox and repeater module       ======
======  step 0 begin to download sandbox package           ======
======  step 1 begin to download repeater module package   ======
======                 install finished                    ======

step1 修改 repeater-config.json,启用拦截点和插件信息

根据需要修改repeater-config.json配置文件,具体配置含义参见:RepeaterConfig.java

repeater-config.json 配置文件,位置是 ~/.sandbox-module/cfg/repeater-config.json

具体的配置含义,官方提供的链接相对路径有问题,无法跳转。可以直接看这个链接:RepeaterConfig.java

此处根据这个被测项目的需要,进行了调整:

20190710 更新:之前的配置遗漏了 javaSubInvokeBehaviors 的设定,会导致回放的时候返回没有被 mock 掉,看不出效果。下面为更正后的配置

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

step2 attach sandbox 到目标进程

先到刚才 clone spring boot 示例项目的根目录,启动被测应用

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

# 查看进程 id 
ps aux | grep target/gs-rest-service-0.1.0.jar
hengjiechen       7737   0.0  0.0  4267932    616 s007  R+   10:23AM   0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn rest-service
hengjiechen       7306   0.0  3.2  7935464 269884 s000  S+   10:23AM   0:14.84 /usr/bin/java -jar target/gs-rest-service-0.1.0.jar

可以看到,进程 id 为 7306 。然后开始 attach

cd ~/sandbox/bin

# 假设目标JVM进程号为'7306' 。-P 是设定 jvm-sandbox 的端口号,后面回放需要用到
./sandbox.sh -p 7306 -P 12580

小技巧:上述的找进程 id + attach 过程,可以用这个命令一键达成:

# -P 是设定 jvm-sandbox 的端口号,后面回放需要用到
sh ~/sandbox/bin/sandbox.sh -p `ps -ef | grep "target/gs-rest-service-0.1.0.jar" | grep -v grep | awk '{print $2}'` -P 12580

控制台输出:

          NAMESPACE : default
            VERSION : 1.2.1
               MODE : ATTACH
        SERVER_ADDR : account.jetbrains.com
        SERVER_PORT : 53866
     UNSAFE_SUPPORT : ENABLE
       SANDBOX_HOME : /Users/hengjiechen/sandbox/bin/..
  SYSTEM_MODULE_LIB : /Users/hengjiechen/sandbox/bin/../module
    USER_MODULE_LIB : /Users/hengjiechen/sandbox/sandbox-module;~/.sandbox-module;
SYSTEM_PROVIDER_LIB : /Users/hengjiechen/sandbox/bin/../provider
 EVENT_POOL_SUPPORT : DISABLE

查看 repeater 日志看模块和插件加载情况

$ tail -200f ~/logs/sandbox/repeater/repeater.log

...
2019-07-07 10:24:14 INFO  initializing logback success. file=/Users/hengjiechen/.sandbox-module/cfg/repeater-logback.xml;
2019-07-07 10:24:14 INFO  module on loaded,id=repeater,version=1.0.0,mode=ATTACH
2019-07-07 10:24:14 INFO  onActive
2019-07-07 10:24:14 INFO  pull repeater config success,config=com.alibaba.jvm.sandbox.repeater.plugin.domain.RepeaterConfig@4dddeb36
2019-07-07 10:24:15 INFO  enable plugin http success
2019-07-07 10:24:15 INFO  add watcher success,type=http,watcherId=1000
2019-07-07 10:24:16 INFO  register event bus success in repeat-register

step3 开始录制和回放

录制几个请求:

➜  complete git:(master) ✗ curl -s 'http://localhost:8080/greeting?name=User'
{"id":1,"content":"Hello, User!"}%                                                                                                                            
➜  complete git:(master) ✗ curl -s 'http://localhost:8080/greeting?name=User2'
{"id":2,"content":"Hello, User2!"}%                                                                                                                           
➜  complete git:(master) ✗ curl -s 'http://localhost:8080/greeting?name=User3'
{"id":3,"content":"Hello, User3!"}%                                                                                                                           
➜  complete git:(master) ✗ curl -s 'http://localhost:8080/greeting'
{"id":4,"content":"Hello, World!"}%

对应看到 repeater 的日志增加了几个输出:

...
2019-07-09 16:31:20 INFO  broadcast success,traceId=192168015059156266108005510001ed,resp=success
2019-07-09 16:31:26 INFO  broadcast success,traceId=192168015059156266108604210002ed,resp=success
2019-07-09 16:31:31 INFO  broadcast success,traceId=192168015059156266109135010003ed,resp=success
2019-07-09 16:31:36 INFO  broadcast success,traceId=192168015059156266109622310004ed,resp=success

好了,试试回放。

怎么回放?文档完全没提到,一脸懵逼。。。等官方文档更新把。

20190709 更新:官方已经更新回放文档啦,接着进行下去。

方式一:利用模块暴露的 http 接口发起回放

官方的说明:

模块暴露了回放接口,用于服务端发起远程回放,具体如下:

url : http://ip:port/sandbox/default/module/http/repeater/repeat
params : _data

其中 port 是 jvm-sandbox 启动时候绑定的 port,可以在 attach sandbox 时增加-P
12580 指定,或者执行~/sandbox/bin/sandbox.sh -p {pid} -v 查看 SERVER_PORT _data
是由 RepeatMeta 经过 hessian 序列化之后的值,具体调用方式参见 AbstractRecordService
和 RecordFacadeApi

没说明是用什么 http 方法(后面通过看 AbstractRecordService.java 看出是 post ),而且 _data 需要用程序做 RepeatMeta 的 hessian 序列化。。。看起来就不是给我们这种命令行触发用的。先跳过。

方式二:针对 HTTP 接口,可以像 Slogan Demo 一样进行参数或者 Header 透传方式进行 MOCK 回放

从前面的 repeater 日志,找到了几个 traceId 。对应把它填到 Repeat-TraceId-X 参数中。(特别留意:回放会根据录制时的 url 进行匹配。如果有参数是通过 url 传递的,必须录制和回放都用一样的参数

# 第一种写法:
$ curl -s 'http://localhost:8080/greeting' -H "Repeat-TraceId-X:192168015059156266109622310004ed"
{"id":4,"content":"Hello, World!"}%  
$ curl -s 'http://localhost:8080/greeting?name=User3' -H "Repeat-TraceId-X:192168015059156266109135010003ed"
{"id":3,"content":"Hello, User3!"}%     

# 第二种写法:
$ curl -s 'http://localhost:8080/greeting?Repeat-TraceId-X=192168015059156266109622310004ed'
{"id":4,"content":"Hello, World!"}%  

id 还在递增,回放没生效。但看了下 plugin 的源码 ,确实是有这样的逻辑。而且上面两个请求发出的时候, repeater.log 并没有输出录制到请求的日志。

20190710 更新:问题已解决,原因是前面的 repeater.json 配置不正确,遗漏了 javaSubInvokeBehaviors 相关配置,导致返回值没有被录制到。

修正后,已经可以输出正确的返回了。此时 repeater.log 也会对应输出日志:

2019-07-10 17:19:25 INFO  initializing logback success. file=/Users/chenhengjie/.sandbox-module/cfg/repeater-logback.xml;
2019-07-10 17:19:25 INFO  module on loaded,id=repeater,version=1.0.0,mode=ATTACH
2019-07-10 17:19:25 INFO  onActive
2019-07-10 17:19:25 INFO  pull repeater config success,config=com.alibaba.jvm.sandbox.repeater.plugin.domain.RepeaterConfig@61e09144
2019-07-10 17:19:25 INFO  enable plugin http success
2019-07-10 17:19:26 INFO  add watcher success,type=http,watcherId=1000
2019-07-10 17:19:26 INFO  enable plugin java-subInvoke success
2019-07-10 17:19:26 INFO  add watcher success,type=java,watcherId=1003
2019-07-10 17:19:27 INFO  register event bus success in repeat-register
2019-07-10 17:19:31 INFO  broadcast success,traceId=192168015059156275037036610001ed,resp=success
2019-07-10 17:19:32 INFO  broadcast success,traceId=192168015059156275037271710002ed,resp=success
2019-07-10 17:19:41 INFO  find target invocation by PARAMETER_MATCH,identity=java://hello.GreetingController/greeting~S,invocation=com.alibaba.jvm.sandbox.repeater.plugin.domain.Invocation@3af687c7
2019-07-10 17:19:52 INFO  find target invocation by PARAMETER_MATCH,identity=java://hello.GreetingController/greeting~S,invocation=com.alibaba.jvm.sandbox.repeater.plugin.domain.Invocation@6b6f0533

最后两行就是对应返回录制的 response 了。

方式三:使用 repeater-console 做回放

官方文档没有明确给出这个方式,但通过查看 repeater-console 里面的 readme ,可以看到它也是有暴露接口供调用的。因此也试试。

结果看了下,里面提供的 standalone 和 mysql 两种数据存储方式,都不支持前面回放的存储方法(存在 ~/.sandbox-module/repeater-data/record 中)。还得调整录制方式才能进行回放。

7.16 更新:此回放方式已跑通。详细的记录,请参照:通用流量录制回放工具 jvm-sandbox-repeater 尝鲜 (二)——repeater-console 使用

  • mybatis + redis

待补充

  • mq

待补充

源码结构简析

项目的源码目录如下:

$ tree -L 2 | grep -v iml
.
├── LICENSE
├── Readme.md
├── bin
│   ├── bootstrap.sh
│   ├── health.sh
│   ├── install-local.sh
│   ├── install-repeater.sh
│   ├── package.sh
│   ├── repeater-config.json
│   ├── repeater-logback.xml
│   └── repeater.properties
├── docs
│   ├── plugin-development.md
│   ├── slogan-demo.md
│   └── user-guide-cn.md
├── hessian-lite
│   ├── pom.xml
│   └── src
├── pom.xml
├── repeater-client
│   ├── pom.xml
│   └── src
├── repeater-console
│   ├── Readme.md
│   ├── pom.xml
│   ├── repeater-console-common
│   ├── repeater-console-dal
│   ├── repeater-console-service
│   ├── repeater-console-start
├── repeater-module
│   ├── pom.xml
│   └── src
├── repeater-plugin-api
│   ├── pom.xml
│   └── src
├── repeater-plugin-core
│   ├── pom.xml
│   └── src
├── repeater-plugins
│   ├── dubbo-plugin
│   ├── http-plugin
│   ├── ibatis-plugin
│   ├── java-plugin
│   ├── mybatis-plugin
│   ├── pom.xml
│   ├── redis-plugin
└── travis.sh

整体结构还是比较清晰的,有 plugin 目录,便于扩展。也有 console 提供最简要的流量管理。更详细的,后续再慢慢研究。

吐槽

20190709 更新:之前提到的 3 个吐槽点官方都第一时间修复了,效率很高。

这次补充两个点:

1、repeater-console 的说明还是太少,虽然通过阅读源码大致了解了它的功能,但不如有文档方便,对新手不大友好。建议补充对应的说明。

2、回放提供的 2 个方式都不是太友好,方式二比较简单,但不支持批量,不适合项目使用。方式一基本上只能通过编程方式进行,无法直接通过接口进行。

建议提供一个命令行工具,可以直接通过命令行参数自动组装和序列化输出 _data 参数,便于用最简单的方式调用回放功能。

小结

这个开源项目是 7 月 4 日 出来的,由于是直接在 jvm 层控制,从原理上是通用性、扩展性最强的。而且目前也提供了 mybatis、http、dubbo 、Java 等插件,redis 预计 7 月放出,基本上覆盖了项目中最常用的几个中间件了。

虽然目前文档还不是非常完整,但看得出来是有在用心维护的,昨天周六也有更新了一版文档,补充了关于原理方面的说明。相信只要有足够的时间,会变得更完善的。

最后,非常感谢阿里能开源一个这么强大的组件,这样一些质量技术方面没法有太多资源投入的公司,也可以把流量录制回放搞起来了。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 61 条回复 时间 点赞

马克,本社区说明最详细最接地气的一篇流量回放的文章。 期待楼主持续更新,楼主吃螃蟹,我吃蟹小爪😂

感谢大佬尝鲜,期待更新!!

赞。效率真高!周末没闲着,这么快就出来这么详细的文章了。

有尝试通过的大神吗?

hello 回复

你这个尝试出效果了吗?

yuzijinrxh 回复

没有,我在等陈大师出后续呢。

026 将本帖设为了精华贴 07月12日 03:12

大佬能给解释下 javaSubInvokeBehaviors,javaEntranceBehaviors 这俩配置项的作用嘛,官方文档看的不是太懂。。。

仅楼主可见
oh_test 回复

个人理解,javaSubInvokeBehaviors 对应子调用,回放时会被 mock 掉(前提是回放时给到的入参和录制时一致),javaEntranceBehaviors 是入口调用,回放时会被作为输入。

举个例子,a 接口对应的 controller 方法是 A,而 A 的实现里面有调用另一个系统的接口,方法是 B 。录制回放主要测试的是 A 方法的逻辑,不想依赖另一个系统。 此时,应该配置 javaEntranceBehaviors 为 A ,javaSubInvokeBehaviors 为 B 。

这样回放时,A 这个入口调用会被原封不动地发给应用进行回放,而 B 这个调用会被 mock 掉,应用实际不会发请求给另一个系统。

GCpigsic 回复

执行 cd complete mvn install && java -jar target/*.jar 之后,你是新开窗口执行 ps aux | grep target/gs-rest-service-0.1.0.jar 的吗?

从你的描述上看,这个 jar 包在 attach 的时候是没有在运行的。

仅楼主可见
GCpigsic 回复

刚找了台 windows 机器结合 git bash 试了下,貌似 ps 不会显示所有进程。可能是 windows 下不支持。

可以试试直接改为用控制台找到的 pid ,继续进行后续的 attach 步骤。

陈恒捷 回复

我试过直接绑定 控制台找到的 pid,继续 attach ,就会出现报这样的错 😭 😭

GCpigsic 回复

好吧。。。

建议弄台 linux 虚拟机,或者给官方提个 issue 。这块比较深入 windows 和 linux 的差异了,我也不大知道怎么解决比较好。

陈恒捷 回复

感谢你!!不得不说,文章真的棒很详细!!!

GCpigsic 回复

感谢支持~

回放竟然还要带上 params,不可思议。。。 常态不应该是只需要 traceId 标识就可以吗,自用的时候发现只用 traceid 也是失败的。。

战 神 回复

额,帖子里说了,回放会根据 url 匹配,因此放在 url 中的参数也需要保持一致。

不过这种回放方式只是用来跑 demo 尝尝鲜。实际项目玩法,建议参考我第二篇文章里提到的 repeater-console 的使用。

陈恒捷 回复

嗯 ,我之前看到帖子里说的了,我之前以为设计思路是直接关联某 id, 再通过某 id 检索到匹配某 ID 的具体信息(如 url,参数 ,头等等)。 检索到后 再拿具体的信息去回放。

战 神 回复

纯回放流量是这样的思路,没问题。 但帖子里的例子是包含了子调用 mock,子调用 mock 记录和入口调用的关联条件之一是 url ,所以需要 url 匹配。

ELes jvm-sandbox-repeater 源码阅读笔记--起始篇 中提及了此贴 08月31日 11:30
仅楼主可见
shifeng5131425 回复

这一步需要在源码根目录下执行,并且要在 bash 命令行环境下运行。 这一步不一定要 linux ,但从上面其它同学的反馈来看,后续有些步骤 windows 可能会跑不了,所以建议是在 linux 虚拟机下执行。

Demo 的录制回放没跑通,有人遇到一样的问题吗?

[xxx@localhost ~]$ curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId=128000000001156034386424510000ed'

JAVA 是世界上最好的语言!

[xxx@localhost ~]$ [xxx@localhost ~]$ [xxx@localhost ~]$ [xxx@localhost ~]$ [xxx@localhost ~]$ [xxx@localhost ~]$ [xxx@localhost ~]$ curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId-X=128000000001156034386424510000ed'

Python 是世界上最好的语言!

[xxx@localhost ~]$
maliang-bj 回复

把你的详细步骤发下?包括怎么启动 repeater 的。

从你的步骤没看出问题,有可能问题在其它步骤里。

maliang-bj 回复

我遇到跟你一样,./bootstrap.sh 之后 2019-10-10 16:31:15.011 INFO 8710 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8001 (http) with context path '' 2019-10-10 16:31:15.021 INFO 8710 --- [ main] c.a.repeater.console.start.Application : Started Application in 10.909 seconds (JVM running for 13.141)

然后录制回放都是不同的返回数据,不知道哪出问题了

maliang-bj 回复

是不是虚拟机环境下的? 如果是需要改一下虚拟配置,你去看 sandbox 日志应该报错了,需改一下虚拟处理器的核心数量,就可以了

太厉害了

这个跟 goreplay 差不多吗?

少年 回复

repeater 的主要特点是,针对写(post)操作,除了录制服务的流入流量,也可以录制服务的外部调用或者特定调用(如数据库查询、第三方服务调用等)。

goreplay 看了下简介,没提及针对写操作的针对性适配,不确定是否也有类似能力。

35楼 已删除
simple [精彩盘点] TesterHome 社区 2019年 度精华帖 中提及了此贴 12月24日 15:00
simple [精彩盘点] TesterHome 社区 2019年 度精华帖 中提及了此贴 12月24日 15:00

想请教下,流量回放如何解决数据问题,比如一个请求 user_id=123,但该请求 user_id 为线上数据,但本地回放如何解决数据不一致问题。难道同步线上数据库?但明显是不合规的。。。

将 sandbox 挂载到应用时 agent 初始化失败 com.sun.tools.attach.AgentInitializationException: Agent JAR loaded but agent failed to initialize ,应用程序控制台报错找不到路径 Caused by: java.io.FileNotFoundException: \c\Users\shito\sandbox\bin..\lib\sandbox-spy.jar (系统找不到指定的路径。),可这个路径是存在的,有童鞋遇到过这个问题吗?

40楼 已删除
rockkk-c 回复

应用程序控制台报错找不到路径 Caused by: java.io.FileNotFoundException: \c\Users\shito\sandbox\bin..\lib\sandbox-spy.jar (系统找不到指定的路径。),可这个路径是存在的,有童鞋遇到过这个问题吗?

能否截图确认下,文件确实存在?

陈恒捷 回复

文件存在 我把 sandbox.sh 这里改了,就没报路径找不到这个错了

请问 windows10 的电脑,安装完成后,无法启动 bootstrap

rockkk-c 回复

赞!

Testjava 回复

路径中有名字带空格的话,需要用双引号括住,否则命令行会把空格当做间隔符隔开不同参数。

个人更建议你直接挪到不带空格的路径下。

仅楼主可见
vengy 回复

这个是 repeater 自动生成的,对于同一个回放记录来说是固定值,类似回放记录自己的唯一 id 。

贴主,为啥我按照你的流程走,不放参数根本不行呢。不管是以 header 方式还是参数方式传入 traceid,都报 500。 带上参数就 OK。 贴主有遇到吗?

失败的: 输入:curl -s 'http://localhost:8080/greeting' -H "Repeat-TraceId-X:010052114254159186298222210001ed" 输出:{"timestamp":"2020-06-11T08:12:55.211+0000","status":500,"error":"Internal Server Error","message":"No message available","path":"/greeting"}

输入:curl -s 'http://localhost:8080/greeting?Repeat-TraceId-X=010052114254159186298222210001ed' 输出:{"timestamp":"2020-06-11T08:17:34.929+0000","status":500,"error":"Internal Server Error","message":"No message available","path":"/greeting"}

成功的: 输入:curl -s 'http://localhost:8080/greeting?name=lisi' -H "Repeat-TraceId-X:010052114254159186298222210001ed" 输出:{"id":11,"content":"Hello, lisi!"}

失败日志: 2020-06-11 16:12:55 INFO find invocation by PARAMETER_MATCH,but similarity not match similarity=0.7,identity=java://hello.GreetingController/greeting~(Ljava/lang/String;) Lhello/Greeting;, invocation=com.alibaba.jvm.sandbox.repeater.plugin.domain.Invocation@57b82d7 2020-06-11 16:17:34 INFO find invocation by PARAMETER_MATCH,but similarity not match similarity=0.7,identity=java://hello.GreetingController/greeting~(Ljava/lang/String;) Lhello/Greeting;, invocation=com.alibaba.jvm.sandbox.repeater.plugin.domain.Invocation@17923ab0

49楼 已删除

我 bootstrap 启动之后一直报数据库连接失败,请问启动前是否有数据库初始化的操作或者配置需要先弄的?

ChristmasBoy 回复

估计过了这么久,官方已经调整了。

问题 1:为什么我的回放,每次都不一样呢😂 问题 2:项目启动完之后,ConfigFacadeApi.java 一直报空指针. appName 和 env 需要提前配置到数据库中吗

追加 repeater-config.json 配置

{
  "degrade": false,
  "exceptionThreshold": 1000,
  "httpEntrancePatterns": [
    "^/regress/.*$"
  ],
  "javaEntranceBehaviors": [
    {
      "classPattern": "com.alibaba.repeater.console.service.impl.RegressServiceImpl",
      "includeSubClasses": false,
      "methodPatterns": [
        "getRegress"
      ]
    }
  ],
  "javaSubInvokeBehaviors": [
    {
      "classPattern": "com.alibaba.repeater.console.service.impl.RegressServiceImpl",
      "includeSubClasses": false,
      "methodPatterns": [
        "getRegressInner"
      ]
    },
    {
      "classPattern": "com.alibaba.repeater.console.service.impl.RegressServiceImpl",
      "includeSubClasses": false,
      "methodPatterns": [
        "findPartner"
      ]
    },
    {
      "classPattern": "com.alibaba.repeater.console.service.impl.RegressServiceImpl",
      "includeSubClasses": false,
      "methodPatterns": [
        "slogan"
      ]
    }
  ],
  "pluginIdentities": [
    "http",
    "java-entrance",
    "java-subInvoke",
    "mybatis",
    "ibatis",
    "dubbo-provider",
    "dubbo-consumer"
  ],
  "repeatIdentities": [
    "java",
    "http",
    "dubbo"
  ],
  "sampleRate": 10000,
  "useTtl": true
}

问题一,我也看不出来有啥错。不过我这个是 1 年前的 demo 了,不确定会不会是官方改了内容

问题二,我这周抽空再试试官方新的 repeater console 模块吧。老模块印象中没有这个接口,所以也没遇到过你的报错。

陈恒捷 回复

关于问题一,完全是按照官方文档操作的。阿里好多开源的东西都是代码更新了,文档不更新😔 关于问题二,项目一启动就报这个错。用的也是他们 master 最新的代码,哎😔

感觉少一个数据库初始化的文件,代码更了 这个没加

在 console 下面有个 sql 文件 你试试

回复错了😂

碰到同样的问题,请教一下,你的这问题解决了么?

@chenhengjie123 陈老师,我在使用 consoleluzhi 录制和回放 java 时,当入参和出参不是基础类型时。提示 ClassNotFound,这个问题应该怎样解决,您有什么建议? 这个问题导致返回数据类型(LinkedHashMap)与实际返回类型(HashMap)不一致。我个人分析是因为 console 没有加载被测应用的 jar 包和类,导致在反序列化的时候无法生成入参对象和出参对象,但是应该怎么样才能加载被测应用的 Jar 包我不了解。

Config 设置: 被测 class: 录制和回放时报的错误:

比对结果: 怀疑问题点:

XJW 回复

正常情况下,当结果为 List 时,结果返回会被转成 LinkedHashMap 比对,上面标记比对结果中 orderType 在结果中第一位,actual 返回没有被转成 LinkedHashMap,所以一直比对失败

XJW 回复

有个疑惑点,好像你 config 配置里的类名,和截图里的被测应用,有点不大一样?

这个情况以前还没怎么遇到过,不大清楚是什么原因。 @kujiale-qa @kujiale 看有没有遇到过?

陈恒捷 回复

是的,config 中是 controll 层的类名,调用了 service 中的 list 方法,我贴成了 service 的实现类,这个图贴的有些问题。

陈恒捷 回复

出现 classNotFound 问题我一直怀疑是方法返回值类型和参数类型是自定义类,在 repeater-console 中未包含。为验证此想法,我将依赖的类和 jar 包在 repeater-console 中创建/引入一遍,目前没有报错了,但这种处理方法违背了工具的初衷。我觉得这个工具应该有更好的方法处理这个问题,请问陈老师有相关的沟通交流群吗?

XJW 回复

repeater 有自己的钉钉沟通群,github 项目 readme 底部有。repeater 的几个主要作者也都在里面。

陈恒捷 回复

钉钉群已然已经过期了 😂

XJW 回复

这。。。你钉钉多少,我拉你?

仅楼主可见
XJW 回复

提示无法找到该用户,你注册钉钉用的是这个邮箱吗?

陈恒捷 回复

抱歉,请再添加一下

XJW 回复

好友请求已发

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册