美文网首页
多数据源的读写分离

多数据源的读写分离

作者: LAMYMAY | 来源:发表于2019-07-28 20:34 被阅读0次

    更新时间: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:服务总是使用的默认数据源,可是我们明明是设置了数据源的啊:解决方法见下图

    image.png

    大概一个场景,
    服务要去访问数据库,那就需要数据源对吧,
    规划指定的服务只能访问指定的数据库【只读的去访问备库,其他的访问主库】

    方案:
    原理是:用注解标识标识服务方法是只读/非只读服务,然后由统一配置去分辨控制什么服务访问主备库。
    最终实现:只读服务访问备库,非只读服务(插删改)访问主库,注意:主备库之间已经做同步

    做法:

    1. 定义注解去标识只读服务(本例子中使用了Spring提供的注解,)

    2. 统一配置:(数据源,AOP,Mybatis集成)
      2.1 数据源配置
      2.2 动态路由配置
      2.3 AOP切服务,绑定相应的key到线程上。目的是动态根据注解去给其设置合适的数据源完成读写分离
      2.4 动态路由选取 map(key-DataSource)

    3. 测试,准备好主备库以、数据、业务方法、接口


    过程中遇到问题:服务一直走默认的主库,
    原因:
    无论什么服务进来后都是获取到了 默认数据源(主库),然后数据没有走备库,
    绑定数据源的时机晚于服务获取数据源,

    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

    相关文章

      网友评论

          本文标题:多数据源的读写分离

          本文链接:https://www.haomeiwen.com/subject/tinprctx.html