多数据库测试提效探索

1.背景

随着互联网的快速发展,传统的单体系统架构已不能满足海量用户的需求。系统的架构大致经历了:单体应用架构--->垂直应用架构--->分布式架构--->SOA架构--->微服务架构的演变。随着架构的演变以及日益增大的流量规模,底层的数据库/表的数量也越来越多,越来越细化。

实际的场景中,一次业务场景往往会涉及到多个数据库/表的变动。以我所在的支付业务的结算场景中最简单流程(未考虑账户创建、权限、商户借款还款等场景)为例:

一共涉及到2个数据库11个表16种单据(仅考虑支付内部的单据流转)。在测试过程中,需要查出各种单据,并对字段进行核验。由于单据分布在不同的库/表,就算提前准备好sql,也需要对单据的关联关系相当熟悉才能快速的查出单据进行核对。整个测试过程中数据库单据核对时间占整体测试时间的大头,数据库查询又占整个单据核对时间的大头,要对测试提效,首先要解决这个问题。2.设计

思路:

通过一个业务单据或者traceId能将整个业务场景所涉及到的单据在同一个页面进行展示

数据表可能是在不同的数据库集群的,因此无法通过数据库原生能力解决该问题,因此需要引入一个"中间商"对业务过程中的数据库操作进行处理,然后进行集中展示。

获取业务过程中数据库变动:

有两个方案

1、通过数据库的binlog进行获取。优点:能够获取到最终的数据,不需要复杂处理。缺点:无法关联业务,只能获取到某个时间段的数据。需要DBA、架构支持

2、通过代码增强,在业务层内获取。优点:能够赋予数据业务场景。不仅仅能够处理MySQL类型数据库。缺点:不是数据库最终数据,处理起来比较麻烦。

同一个时间段内,会有多个需求同时进行测试,某个时间段内会有很多干扰的数据,因此binlog并不太明满足我们的需求,因此选了方案2。

3.技术实现

3.1 代码增强

转转在测试环境中所有集群都接入了jvm-sandbox,因为直接使用jvm-sandbox的能力进行增强即可。

因为需要知道SQL的执行结果,因此需要监听RETURN和THROWS事件(不关心异常,监听Return即可)

传送门:github.com/alibaba/jvm...

3.2 增强点

jdbc执行流程:装载驱动 -> 建立connection -> 创建statement(prepareStatement) -> 执行SQL语句(executeInternal)我们需要获取到已经准备好的SQL语句,因此需要在executeInternal处进行增强jdbc有两个版本,因为不确定服务使用的是哪个版本,为了减少配置,都需要进行增强。

在module内通过反射调用PreparedStatement#asSql()即可获取SQL语句

3.3 业务关联

转转接入了transmittable-thread-local,在流量起点会生成一个traceId在服务间传递,因此只需要将traceId与sql绑定即可。

传送门:github.com/alibaba/tra...

3.4 SQL处理

我们只需要关注变动的数据,因此我们只需要关心INSERT、UPDATE、DELETE语句。

通过对这三种SQL的解析,最终得到以下数据:

3.5 事务处理

如果在执行SQL的时候开启了事务,我们从RETURN事件中获取到的并不是最终提交的数据,因此我们需要感知到事务的提交和回滚。

MYSQL 事务处理主要有两种方法

1、用 BEGIN, ROLLBACK, COMMIT来实现

  • BEGIN 开始一个事务
  • ROLLBACK 事务回滚
  • COMMIT 事务确认

2、直接用 SET 来改变 MySQL 的自动提交模式:

  • SET AUTOCOMMIT=0 禁止自动提交
  • SET AUTOCOMMIT=1 开启自动提交

通过对多个数据库框架源码的阅读,大部分采用的都是第二种:开启事务时将AUTOCOMMIT=0,事务结束之后主动调用commit并恢复AUTOCOMMIT=1。

因此我们可以对下面三个地方进行增强:

setAutoCommit(false),增加一个ThreadLocal用来存储SQL。

commit或setAutoCommit(true),标记事务已提交,并发送数据

rollback,标记事务已回滚,并发送数据。

3.6 前端展示

最终呈现示例:

4.未来优化

1、兼容更多的数据库:redis、es等

2、提供类似Charles、fiddler类似,实时抓取数据库变更页面

3、根据流量入口进行数据归类

作者:陈俊华
转转研发中心及业界小伙伴们的技术学习交流平台,定期分享一线的实战经验及业界前沿的技术话题。
关注公众号「转转技术」(综合性)、「大转转FE」(专注于FE)、「转转QA」(专注于测试),更多干货实践,欢迎交流分享~

相关推荐
帅得不敢出门1 天前
安卓使用memtester进行内存压力测试
android·压力测试·测试·硬件测试
每周都想吃火锅7 天前
如何在postman中传入文件参数
postman·测试
HinsCoder9 天前
【测试】——Selenium API (万字详解)
自动化测试·笔记·学习·selenium·测试工具·web·测试
大柏怎么被偷了11 天前
【测试】什么是需求?
测试
郝同学的测开笔记12 天前
PyQt6 中的布局管理
后端·python·测试
南风与鱼13 天前
软件测试 BUG 篇
bug·测试
四格13 天前
如何使用 Bittly 进行基于串口的自动化测试
嵌入式·测试
Lossya15 天前
【自动化测试】常见的自动化遍历工具以及如何选择合适的自动化遍历工具
自动化测试·功能测试·测试工具·自动化·测试
HinsCoder15 天前
【渗透测试】——Upload靶场实战(1-5关)
笔记·学习·安全·web安全·渗透测试·测试·upload靶场
大柏怎么被偷了16 天前
【软件测试】测试的岗位有哪些?
软件测试·测试