JVM-SandBox-Repeater 试错

原教程地址查看 【GITHUB教程地址】

本帖只记录遇到的错误以及对应的解决办法。

数据库字段报错

问题描述如下

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'moduleconf0_.app_name' in 'field list'

这是因为Repeater代码必须使用数据库进行存储操作,而新入门的情况下,本地应该都没有搭建好数据库,所以必然会报这个错误。

而类似的问题很多,如果手动一个个去试验的找出所有数据库表和字段明显不靠谱,耗时耗力不说,还非常容易漏掉字段或者字段类型出现问题,导致最终无法下手。

而一般情况下,应该都会有对应的.sql文件去兜底这件事。所以找到.sql文件应该能解决这个问题。

往下查看报错信息,会发现如下内容

at com.alibaba.repeater.console.dal.dao.ModuleConfigDao.query(ModuleConfigDao.java:48) ~[repeater-console-dal-1.0.0-SNAPSHOT.jar!/:na]
at com.alibaba.repeater.console.service.impl.ModuleConfigServiceImpl.query(ModuleConfigServiceImpl.java:69) ~[repeater-console-service-1.0.0-SNAPSHOT.jar!/:na]
at com.alibaba.repeater.console.start.controller.api.ConfigFacadeApi.getConfig(ConfigFacadeApi.java:33) ~[classes!/:na]

会发现和JVM-SandBox-Repeater有关的报错只有这三行,逐一查找jar包反编译后的文件,会在 jvm-sandbox-repeater/repeater-console/repeater-console-dal/target/classes/database.sql 这个文件中找到所有的数据库表和字段内容。

直接使用这个文件创建数据库,即可解决这个问题。

空指针问题

问题描述如下

java.lang.NullPointerException: null

java中不要太常见的问题。这个问题主要出现在以下代码的最后一行

@RequestMapping("/config/{appName}/{env}")
public RepeaterResult getConfig(@PathVariable("appName") String appName,
                                                @PathVariable("env") String env) {
    ModuleConfigParams params = new ModuleConfigParams();
    params.setAppName(appName);
    params.setEnvironment(env);
    RepeaterResult result = moduleConfigService.query(params);
    return RepeaterResult.builder().success(result.isSuccess()).message(result.getMessage()).data(result.getData().getConfigModel()).build();
}

getConfig 方法在返回数据时,会从数据库获取对应 appNameenv 的数据,而全新环境下,数据库没有任何内容,所以只能获得一个空值,最终导致空指针错误。

通过名字可以比较明显的看出来,只需要往 module_config 表中插入数据,应该可以解决这个问题。

最后把原生配置文件中的内容作为config,插入一条新的配置数据导数据库,具体如下

insert into module_config (gmt_create, gmt_modified, app_name, environment, config) values ('2020-11-23 08:04', '2020-11-23 08:04', 'repeater', 'daily', '{ "useTtl" : true, "degrade" : false, "exceptionThreshold" : 1000, "sampleRate" : 10000, "pluginsPath" : null, "httpEntrancePatterns" : [ "^/regress/.*$" ], "javaEntranceBehaviors" : [ { "classPattern" : "com.alibaba.repeater.console.service.impl.RegressServiceImpl", "methodPatterns" : [ "getRegress" ], "includeSubClasses" : false } ], "javaSubInvokeBehaviors" : [ { "classPattern" : "com.alibaba.repeater.console.service.impl.RegressServiceImpl", "methodPatterns" : [ "getRegressInner", "findPartner", "slogan" ], "includeSubClasses" : false } ], "pluginIdentities" : [ "http", "java-entrance", "java-subInvoke" ], "repeatIdentities" : [ "java", "http" ] }');

这样,上面的代码就可以正常的从数据库获取到一条数据。

此时再执行如下命令,就可以正确的进行回放

# 重新编译代码
mvn clean install -Dmaven.test.skip=true
# 启动
./bin/bootstrap.sh
# 录制
curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId=127000000001156034386424510000ed'
# 回放
curl -s 'http://127.0.0.1:8001/regress/slogan?Repeat-TraceId-X=127000000001156034386424510000ed'

如无意外,回放时会返回

JAVA是世界上最好的语言!

录制自己的应用时,没能捕获到数据

解决完上面两个问题后,教程的第一步,standalone 模式的录制和回放已经无法再满足我了,于是继续向下看,准备录制自己的应用流量。

修改完 repeater-config.json 文件,只保留了 http 请求的流量,将正则匹配中的 regress 也改为自己的接口路径的内容后,发现 repeater.log 中依然只有冷冰冰的启动成功的提示,没有更多的日志。

一番折腾下,终于想起来修改日志等级,打开 ~/.sandbox-module/cfg/repeater-logback.xml ,将日志等级从 info 调整为 debug,最终如下所示




    
        ${user.home}/logs/sandbox/repeater/repeater.log
        
            ${user.home}/logs/sandbox/repeater/repeater.log.%d{yyyy-MM-dd}
            30
        
        
            %d{yyyy-MM-dd HH:mm:ss} %-5level %msg%n
            UTF-8
        
    
    
    # 修改这里
    
        
    


再次编译启动 repeater-console,重启 repeater 之后,发现多了一堆信息,其中有一条为 current uri {你的请求路径} can't match any httpEntrancePatterns, ignore this request

所以确认是正则匹配失败导致的,全局搜索一下这句话,很方便能找到如下的代码

# HttpStandaloneListener.java
private boolean matchRequestURI(List patterns, String requestURI) {
    if (CollectionUtils.isEmpty(patterns)) {
        return false;
    }
    for (String pattern : patterns) {
        if (requestURI.matches(pattern)) {
            return true;
        }
    }
    return false;
}

如果对于正则不是很有信心,可以将代码拷贝出去一个个的试,得到正确的匹配规则集。

将试验后返回true的正则更新到配置文件后,再次编译启动 repeater-console,重启 repeater ,发送请求后,会在数据库中正确查看到新录制到的流量信息。

至此,在服务器数据库环境下录制流量的任务就算完成了。

总结

总的来说 standalone 模式下的流程和非 standalone 模式的流程还是非常相似,都是将录制到的数据保存到数据库。

在调试通单机模式后,再去录制自己的应用流量时,会简单很多,不过我还是在正则这块卡了比较久,一个是对于Java正则的不熟悉,另一个可能也是惯性思维,让我认为只要把 regress 这个单词替换了应该其他的也行的通。

虽然经过一番折腾算是在服务器将流量录制好了,但是就教程来说,依然槽点满满,是一份照本宣科后无法入门的教程,而且一年多没更新了,劝退能力MAX,我一度怀疑是代码更新了比较多,但是教程没有及时更新导致我卡了不少地方。

你可能感兴趣的:(JVM-SandBox-Repeater 试错)