Mock 服务设计与实现:MySQL 驱动字节码修改增强
摘要:华为导流测试平台通过对线上流量回放到被测环境中,利用线上真实流量进行充分测试,保证业务系统稳定上线。但是业务在导流测试过程中现网数据库往往难以同步到测试环境,导致现网数据无法正常回放,测试价值降低。由此提出回放过程中对数据库进行 mock,以保证回放过程正常进行。
一、需求分析
1.背景
华为导流测试平台通过对线上流量回放到被测环境中,利用线上真实流量进行充分测试,保证业务系统稳定上线。但是业务在导流测试过程中现网数据库往往难以同步到测试环境,导致现网数据无法正常回放,测试价值降低。由此提出回放过程中对数据库进行 mock,以保证回放过程正常进行。
2.方案分析
数据库 Mock 方案大致分为以下 3 种:

3.方案对比


二、方案 2:MySQL 驱动字节码修改增强方案详细说明
1.方案设计
字节码增强:通过分析 MySQL 数据库驱动源码可知,获取数据库返回的 ResultSet 结果集的方法在 com.mysql.jdbc.PreparedStatement 类中的 executeQuery 方法,和执行完 execute 方法之后再调用 getResultSet 方法两种方式,所以我们需要对 executeQuery 和 execute 两个方法进行字节码修改增强。即在这两个方法执行完成之后,注入以下代码:获取 Mock 文件中的行列数据,转成 MySQL 需要的字节码对象,再设置到 ResultSet 实例化对象中替换原数据库的真实数据即可。

Mock 数据设计和解析:一次请求链路中,比如有下面三次查询语句,并且存在相同 sql 执行多次并且返回结果不同的情况,那么我们在回放请求过程时,就得按顺序去依次取得每条 sql 执行的结果数据,而且能做到可对链路中其中一些 sql 结果进行 mock,不 mock 的 sql 返回数据库的真实数据。

2.使用说明
1.在需要数据库 Mock 功能的第三方服务的启动命令中增加-javaagent 参数指向该 jar 包,方式如下:
java -javaagent:D:/dbmockagent.jar -jar **.jar
2.参数设置:
(1)可设置 dbmock.file 参数指定 Mock 数据文件,不设置时默认为 C:/dbmock.data。目前只实现了从文件中读取 mock 数据,可扩展从接口等其它地方获取 Mock 数据。
java -javaagent:D:/dbmockagent.jar -Ddbmock.file="D:/dbmock.data" –jar **.jar
(2)可设置 dbmock.port 参数指定重载 Mock 数据接口调用的端口,可不设置,默认为 8888:
java -javaagent:D:/dbmockagent.jar -Ddbmock.file="D:/dbmock.data" -Ddbmock.port=8088 -jar **.jar
3.方案测试
3.1 使用 MySQL 驱动直连数据库

3.1.1 不使用插件

3.1.2 使用插件

再次运行上面的代码,执行结果如下,输出了 DBMock 相关的 log 信息,返回的数据正好为上面 mock 的数据,并且两次 sql 语句虽然相同,但是返回的结果数据是按照 mock 文件里的顺序返回的。

3.2 SpringBoot 工程中通过 MyBatis 连接数据库


3.2.1 不使用插件


3.2.2 使用插件


3.3 Mock 数据更新



本文分享自华为云社区《数据库 Mock 方案设计》,原文作者:chenhuaping 。
版权声明: 本文为 InfoQ 作者【华为云开发者社区】的原创文章。
原文链接:【http://xie.infoq.cn/article/d10abe93643af3d6938e1f331】。文章转载请联系作者。
评论