基于jvm-sandbox的mock项目:iMock 实现过程遇到的问题及解决

imock项目地址https://github.com/chufusheng/imock-web,作者很nice,中间沟通了很多次,感谢支持!!!

 

团队年度目标有一个搭建Mock平台任务,落到了我头上。

1、首先明确团队的需求

请求+响应由用户自己定义

启用,返回定义的响应结果

停用,返回自己服务的结果

2、调研分为两种方案

2.1 jvm-sandbox的mock服务,底层方法级别,功能满足,但操作相对复杂

2.2 Moco的mock服务,满足使用,简单易操作,团队想要平台级别,如果只是一个小工具的话有点勉强

3、方案实现过程

3.1 调研过程,开发基于阿里中间件 jvm-sandbox的mock服务,Java方法级别的mock,操作就是监听指定方法,返回指定的mock内容

3.2、阿里官方提供的demo「修复的钟」实现完成(网上很多不体现具体操作了)

目的:a.理解jvm-sandbox的mock的实现原理; b.给leader过程演示使用

缺点:被测试服务中【手动接入mock;以demo作为基础可以做一个mock工具使用也可以支持。

Ø 手动安装sandbox;

Ø 手动查询被测试服务PID

Ø 手动启动sandbox

3.3imock的搭建

看到作者在GitHub上的贴图,感觉很适合做为一个平台项目使用,继续往下走。

下完后端和前端代码,编译前端代码各种配置冲突,看到后端有提供html页面,弃用了前端服务,精力有限啊。。

编译后端代码,解决各种冲突,开始本机装的mysql8以上,java8,后面还是换了mysql5(建议用mysql5),pom文件直接用作者的就可以。

 

第一步:数据初化 https://github.com/chufusheng/imock/tree/main/bin/sql 

创建2张表,顺利完成。

第二步:启动mock服务管理后台 mock-web

mysql5+java8,配置好idea基本上不会有配置冲突,可以编译成功,服务也就起来了;

第三步:启动前端项目 imock-web(跳过)

第四步:安装mock-module(默认会安装jvm-sandbox)

本地安装 到项目下的bin目录执行 install-local.sh;「提示⚠️:GitHub上作者提供的文件中命令需要修改。作者直接邮件发了我一份,完美解决」

远程安装到目标应用curl -s https://kunchu.oss-cn-beijing.aliyuncs.com/install-troublemaker.sh |sh「项目还没部署到服务器,暂时没用到」

第五步:配置目标应用

通过配置文件配置 进入根目录下的隐藏目录 ~/.sandbox-module/cfg 修改mock.properties「提示⚠️:mock.host=http://127.0.0.1:8003,这个是mock服务的地址」

 

 

 

启动被测应用时带上 java 环境变量「上面已经配置了app.name 、app.env,这里不用带」

 

 

第六步:启动

ü 通过jps查看 被测应用的java 进程 比如 1234(启动被测服务的终端上,会直接显示进程号,直接复制使用)

ü 到根目录 ~/sandbox/bin 执行 ./sandbox.sh -p 1234

ü 被测试服务与mock服务建立心跳(这里之前一直没有获取到被测服务的应用,排查了好几遍debug日志,最后和作者沟通后,发现是配置的mock.host是被测服务的😂,应该是mock服务的)

排查过程:

//跟踪建立心跳的过程,发现是jvm-sandbox的底层代码实现的;
//附上阿里云上的源码解析https://developer.aliyun.com/article/716768
class AppTask 每小时检查1次Status;
interface ModuleInfoService 查询Status,getAppHeart
class MockResult<T> 
class ResultHelper
class ModuleConfigServiceImpl,stopAndOpen 操作开关

class ModuleInfo implements java.io.Serializable :在线模块信息

//通过jvm.sandbox获取被测试应用信息,建立心跳
class HeartbeatHandler
interface ConfigInfo(jvm.sandbox)
class MockModule
interface ModuleEventWatcher(jvm.sandbox)
interface LoadedClassDataSource(jvm.sandbox)

过程排查的问题:

 

 

问题1:建立心跳后,点击「冻结」或「更新配置」按钮,接口返回:

success: false
message:"Invoke failed, status code is not 200

debug日志:Column ‘createTime’ cannot be null

报错原因是:

我用的是Mysql8,explicit_defaults_for_timestamp 系统变量决定MySQL服务端对timestamp列中的默认值和NULL值的不同处理方法。

此变量自MySQL 5.6.6 版本引入,分为全局级别和会话级别,可动态更新,默认值为OFF。

8.0之中默认值改为了on。

解决方法:最好还是安装mysql5吧。

 

 

debug过程中,还有其他异常报出来,都看了一遍,不影响运行,可以忽略:

问题org.springframework.boot:type=Admin,name=SpringApplication(log-debug引起)

 

问题java.lang.reflect.InaccessibleObjectException

 

问题no tcnative-1 in java.library.path, no libtcnative-1 in java.library.path(只是优化,不是error

 

问题Use of DefaultSchemaNameResolver requires Dialect to provide the proper SQL statement/command but provided Dialect(框架内部抛出的异常)

 

问题Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.

 

问题Http11Processor : Error parsing HTTP request header(因为tomcat自8.5.x系列对于非保留字字符(json格式的请求参数)必须做转义操作)

 

至此,可以建立稳定心跳,顺利获取被测应用的信息了。。

后面还有就是配置后,请求接口时没有返回mock的响应结果,正在和项目作者沟通,忽听闻我leader被撤了😂,,,人生无常啊

 

posted @ 2023-03-14 14:07  迷迷糊糊的礼物  阅读(636)  评论(3编辑  收藏  举报