
Java:基于AOP的动态数据源切换
1 动态数据源的必要性
我们知道,物理服务机的CPU、内存、存储空间、连接数等资源都是有限的,某个时段大量连接同时执行操作,会导致数据库在处理上遇到性能瓶颈。而在复杂的互联网业务场景下,系统流量日益膨胀。为了解决这个问题,行业先驱们充分发扬了分而治之的思想,对大库表进行分割,然后实施更好的控制和管理,同时使用多台机器的CPU、内存、存储,提供更好的性能。参考我这篇《分库分表》。
数据库有水平拆分(Scale Out) 和垂直拆分(Scale Up)的区别,但是无论怎么变化,当你对同一业务库进行分库的时候。必然要考虑到,在你的同一个业务服务(Service),会有同时访问多个数据源的情况。如下图
另外一种场景是ABTesting业务场景,可能不同的用户看到的业务数据是不一样的,这就需要根据业务特性动态的获取数据。
按照Spring boot的常规做法,maven添加依赖,在Yaml中配置对应的datasource、jpa等属性即可使用了。但是多数据源的情况下无论是配置 还是数据上下文的切换都变得无比繁琐。如果能使用注解声明的方式,粒度细化到方法级别的,那用起来就简单多了。那我们来写一个这样的实现。
2 实现过程
2.1 Maven依赖
pom文件中增加一些依赖,这边我们以Jpa为案例说明:
2.2 yaml配置
可以看到我们配置了一个默认的数据源basic,然后再扩展了一个跟basic同级的节点mutil-data-core,包含三个数据源,basic、cloudoffice、attend。
2.3 编写配置类Configuration
扫描我们上面的配置,spring.mutildata.basic下面的默认数据源,以及 mutil-data-core下面的多个动态数据源,有多少个扫描多少个出来,并进行组装,放到一个数据源map集合中:dataSourceMap。
2.4 数据源集合
数据源的管理:包含组织数据源、读值、赋值、清空数据源等。
2.5 按键查找
无注解的情况下,lookupKey是空的,这边直接提供默认数据源。
有注解的时候,按照注解中的信息进行查找。
2.6 初始化后的数据源结构
注意它的key,跟我们配置中的一模一样,basic、cloudoffice、attend。这个很重要,注解用这个来匹配。
2.7 编写Annotation
写一个注解,映射的目标范围为 类型和方法。
2.8 编写AOP实现
编写切面代码,以实现对注解的PointCut。
2.9 测试与效果
2.9.1 数据源key信息
数据源key 信息,有多少个数据源,这边就配置多少个,注意值须与yaml配置中的值保持一致。
2.9.2 测试方法
在Control中写三个测试方法
2.9.3 效果
3 总结和代码参考
如果需要扩展数据源,在yaml的节点mutil-data-core下加配置数据就行了,简单方便。后面再写个MyBatis的实现方式。
github代码:https://github.com/WengZhiHua/Helenlyn.Grocery/tree/master/parent/DynamicDataSource
