更新时间:2019-07-28
多数据源的读写分离:
源码(包含数据库脚本): https://github.com/lamymay/ds.git
方案:
继承org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
向框架传递线程将调用哪个数据源,(返回的不同key到sqlSessionFactory中获取对应数据源然后使用ThreadLocal来存放线程的变量,将不同的数据源标识记录在ThreadLocal中)
配置再通过AOP实现动态数据源切换
文章参考:https://www.cnblogs.com/zdd-java/p/zdd_datasource_aop.html
出现一个bug:服务总是使用的默认数据源,可是我们明明是设置了数据源的啊:解决方法见下图
大概一个场景,
服务要去访问数据库,那就需要数据源对吧,
规划指定的服务只能访问指定的数据库【只读的去访问备库,其他的访问主库】
方案:
原理是:用注解标识标识服务方法是只读/非只读服务,然后由统一配置去分辨控制什么服务访问主备库。
最终实现:只读服务访问备库,非只读服务(插删改)访问主库,注意:主备库之间已经做同步
做法:
-
定义注解去标识只读服务(本例子中使用了Spring提供的注解,)
-
统一配置:(数据源,AOP,Mybatis集成)
2.1 数据源配置
2.2 动态路由配置
2.3 AOP切服务,绑定相应的key到线程上。目的是动态根据注解去给其设置合适的数据源完成读写分离
2.4 动态路由选取 map(key-DataSource) -
测试,准备好主备库以、数据、业务方法、接口
过程中遇到问题:服务一直走默认的主库,
原因:
无论什么服务进来后都是获取到了 默认数据源(主库),然后数据没有走备库,
绑定数据源的时机晚于服务获取数据源,
debug 现象也说明了这点,AOP切着这些服务,当服务获取数据的时候,还没有绑定合适的数据源,则它就先去获取到了 默认数据源(主库),导致一直不走备库。实际上AOP在比较晚的时机才把合适的数据源设置给他,
人话就是,我还没有给他合适的数据源,他就早早获取了一个不合适的数据源去勾搭数据库去了
先看图,代码不用复制,移步github,检出后创建两个数据库跑两条sql即可验证,代码中持久层使用的mybatis,(JPA版本的有一个别人做好的例子晚点找到源地址了也贴一下)
(数据库的同步,请寻求另外的教程,这里只讲读写分离客户这端的实现)
1注入多DS--java config
image.png
2配置文件--yml
image.png
3路由DS
image.png
4集成Mybatis
image.png
5路由key 获取设置逻辑 ThreadLocal<DynamicDataSourceType>
image.png
6在AOP中把把路由key绑定到 ThreadLocal<DynamicDataSourceType>
image.png
7使用非spring默认连接池的需要在配置一下连接池啊,请悉知
//测试说明 :
//@GetMapping("/files/{id}") 走 test5的db
//@GetMapping("/files") 走test的db
网友评论