基于jvm-sandbox的imock开发指南详解

 更新时间:2023年08月11日 09:06:42   作者:李梨同学  
这篇文章主要为大家介绍了基于jvm-sandbox的imock开发指南详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

需求

  • 支持java后端服务方法级别的mock,对没有测试环境的第三方服务进行mock,增加团队覆盖率。
  • 启用,返回用户自定义的mock响应结果
  • 停用,返回服务本身的结果

通过一系列调研,最终工具选型了基于 jvm-sandbox的mock服务,是Java方法级别的mock,操作就是监听指定方法,返回指定的mock内容。

1、项目介绍

imock 包含mock-module、mock-web ,mock-module就是jvm-sandbox的模块,需要安装到目标应用服务器,mock-web 为mock服务后台,imock是前后端分离,还有一个前端react 项目 imcok-web

ume_mock_backend :http://git1.local.umetrip.com/guanhongli/ume_mock_backend

ume_mock_frontend :http://git1.local.umetrip.com/guanhongli/ume_mock_frontend

2、imock使用

首先将前后端项目都跑起来,安装依赖啥的先把环境调通。

2.1、启动imock-web

本地环境:直接idea启动即可

容器环境:java -jar启动

nohup java -jar /opt/applog/MskyLog/mock/mock-web.jar > myout.txt 2>&1 &

2.2、准备mock-module

2.2.0.本地安装

到项目下的bin目录执行 install-local.sh,通过脚本编译mock-module,如需修改代码要重新执行此脚本。

2.2.1.修改cfg

# 心跳上报配置  当环境变量没有配置的时候使用 该配置
# mock 服务的地址和端口
mock.host=http://172.24.146.219:8003
# 标识目标应用的名称
app.name=test-umeapp-checkin
# 标识目标应用的环境
app.env=test-umeapp-checkin

2.2.2.拷贝到sandbox-module目录

将cfg和mock-module拷贝到sandbox/sandbox-module目录下。

cd /opt/applog/MskyLog/mock
cp /opt/applog/MskyLog/mock/mock-module.jar  /opt/app/sandbox/sandbox-module
cp -r /opt/applog/MskyLog/mock/cfg  /opt/app/sandbox/sandbox-module

2.2.3.拷贝到.sandbox-module目录

cp /opt/applog/MskyLog/mock/mock-module.jar /opt/app/.sandbox-module

2.2.4.创建mock日志目录

mkdir -p /home/jboss5/logs/sandbox/mock/

2.3、attch挂载目标应用

jps命令查看pid

cd /opt/app/sandbox/bin/
./sandbox.sh -p 22

2.4、查看log

2.4.1、查看sandbox.log

tailf /opt/applog/MskyLog/sandbox/sandbox.log

2.4.2、查看mock.log

tailf /home/jboss5/logs/sandbox/mock/mock.log

2.4.3、查看服务log

结合log和error日志来看

tailf /opt/applog/MskyLog/UmeCki/UmeCki_info.log
tailf /opt/applog/MskyLog/UmeCki/UmeCki_trace.log
tailf /opt/applog/MskyLog/UmeCki/UmeCki_err.log

3、遇到的问题

3.1、mock切面问题,增加before返回

看代码mock逻辑是在afterReturning中实现的,这样的话是不是原代码逻辑还是会执行,只是修改了返回给调用方的Object或者Exception。比如我想mock调用银行支付逻辑,但是还是会实际支付,所以切面放在before(Advice advice)并且结合returnImmediately会不会效果更好。

作者的代码afterReturning方法是通过advice.getReturnObj().getClass()来获取类,然后把ro.getReturnData()序列化到对象中。

  • 如果before方法,则advice.getReturnObj()为空,空指针无法获取类对象。
  • 如果mock方法的值返回为空,则依然无法获取对象类型。

因此需要换一个方法获取类对象

使用advice.getTarget()方法来获取对象类型,使用advice.getBehavior()获取方法名称。

Method method = advice.getTarget().getClass().getMethod(advice.getBehavior().getName());
returnType = method.getGenericReturnType();
LogUtil.info2("returnType=", String.valueOf(returnType));
Object res1 = JSON.parseObject(ro.getReturnData(), returnType);
LogUtil.info2("res1=", res1.toString());

但经过测试只有springboot可以用,dubbo接口advice.getTarget()为空。

在 Dubbo 中,advice.getTarget() 返回 null 可能是由于 Dubbo 的代理机制导致的。Dubbo 使用代理对象来实现远程服务的调用,代理对象是在运行时动态生成的,而真正的目标对象是通过 Dubbo 的远程调用机制获取的。因此,在 Dubbo 的 Advice 中,advice.getTarget() 返回的是代理对象,而不是真正的目标对象。由于代理对象并不是目标对象本身,因此可能返回 null

在 Spring Boot 中,advice.getTarget() 返回的是目标对象,因为 Spring Boot 使用的代理机制与 Dubbo 不同。Spring Boot 中的 AOP 代理通常是通过 JDK 动态代理或 CGLIB 生成的,这些代理对象会保留对目标对象的引用,因此在 Advice 中调用 advice.getTarget() 可以获取到目标对象的引用,不会返回 null

接着找其他的办法。。。

通过advice.getBehavior().getReturnType()

Method method = advice.getBehavior().getReturnType().getMethod(advice.getBehavior().getName());

完美解决!

// 获取方法的返回对象类型
Object res1 = JSON.parseObject(ro.getReturnData(), advice.getBehavior().getReturnType());
LogUtil.info2("res1=", res1.toString());

3.2、报错time字段不为空

解决办法:修改数据库让字段可以为空。

3.3、imock-web

java.lang.TypeNotPresentException: Type org.springframework.boot.maven.RepackageMojo not present

后续

至此,通过本地调试,二次开发imock已经能够符合我们公司的需求,后续再针对个性化的需求进行开发,更多关于jvm-sandbox imock开发的资料请关注脚本之家其它相关文章!

相关文章

  • Springboot集成mqtt客户端详解

    Springboot集成mqtt客户端详解

    MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。本文为大家分享了Springboot整合mqtt服务的示例代码,需要的可以参考一下
    2022-10-10
  • springboot整合springsecurity与mybatis-plus的简单实现

    springboot整合springsecurity与mybatis-plus的简单实现

    Spring Security基于Spring开发,项目中如果使用Spring作为基础,配合Spring Security做权限更加方便,而Shiro需要和Spring进行整合开发。因此作为spring全家桶中的Spring Security在java领域很常用
    2021-10-10
  • 基于Java实现抽奖系统

    基于Java实现抽奖系统

    这篇文章主要为大家详细介绍了基于Java实现抽奖系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • Java发送http请求的示例(get与post方法请求)

    Java发送http请求的示例(get与post方法请求)

    这篇文章主要介绍了Java发送http请求的示例(get与post方法请求),帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2021-01-01
  • 一文教你如何使用原生的Feign

    一文教你如何使用原生的Feign

    Feign使得 Java HTTP 客户端编写更方便,Feign 灵感来源于Retrofit、JAXRS-2.0和WebSocket,这篇文章主要给大家介绍了如何使用原生的Feign的相关资料,需要的朋友可以参考下
    2021-10-10
  • java在linux系统下开机启动无法使用sudo命令的原因及解决办法

    java在linux系统下开机启动无法使用sudo命令的原因及解决办法

    每次开机自动启动的java进程,页面上的关机按钮都无法实现关机功能,但是此时如果以chb账号通过ssh登录该服务器,手动杀掉tomcat进程,然后再重新启动tomcat,页面上的关机按钮就有效了
    2013-08-08
  • Java工厂模式定义与用法实例分析

    Java工厂模式定义与用法实例分析

    这篇文章主要介绍了Java工厂模式定义与用法,结合具体实例形式分析了java工厂模式定义、使用相关操作技巧,并总结了类图原理,需要的朋友可以参考下
    2019-07-07
  • 详解Java无需解压直接读取Zip文件和文件内容

    详解Java无需解压直接读取Zip文件和文件内容

    本篇文章主要介绍了详解Java无需解压直接读取Zip文件和文件内容,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • Mybatis日志配置方式(slf4j、log4j、log4j2)

    Mybatis日志配置方式(slf4j、log4j、log4j2)

    这篇文章主要介绍了Mybatis日志配置方式(slf4j、log4j、log4j2),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • idea 访问html页面端口号显示的是63342而不是8080

    idea 访问html页面端口号显示的是63342而不是8080

    这篇文章主要介绍了idea 访问html页面端口号显示的是63342而不是8080,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08

最新评论