【高可用】利用AOP实现数据库读写分离

最近项目中需要做【高可用】数据库读写分离相关的需求,特地整理了下关于读写分离的相关知识。项目中采用4台数据库:1个master,2个slave,1个readOnly,其中master数据库会自动定时同步到readOnly节点。可以通过中间件(ShardingSphere、mycat、mysql-proxy 、TDDL …), 但是我们公司没有专门的中间件团队搭建读写分离基础设施,因此需要开发人员自行实现读写分离(有点离谱~)。

一、实现原理

Spring框架中,Spring-JDBC模块提供了AbstractRoutingDataSource,其内部可以包含了多个DataSource,通过继承该类并覆盖determineCurrentLookupKey方法,可以根据业务需求动态选择数据源。

二、具体实现

1、application.yml配置读和写数据源

server:
  port: 8080

spring:
  datasource:
    druid:
      ds1:
        url: jdbc:mysql://localhost:3306/db_ds1?serverTimeZone=UTC&useUnicode=true&characterEncoding=UTF-8&useSSL=false
        username: root
        password: root1234
        driver-class-name: com.mysql.jdbc.Driver
      ds2:
        url: jdbc:mysql://localhost:3306/db_ds2?serverTimeZone=UTC&useUnicode=true&characterEncoding=UTF-8&useSSL=false
        username: root
        password: root1234
        driver-class-name: com.mysql.jdbc.Driver

2、DynamicDataSource动态数据源,继承AbstractRoutingDataSource,实现determineCurrentLookupKey方法

/**
 * 动态数据源
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
   

    /**
     * ThreadLocal 用于提供线程局部变量,在多线程环境可以保证各个线程里的变量独立于其它线程里的变量。
     * 也就是说 ThreadLocal 可以为每个线程创建一个【单独的变量副本】,相当于线程的 private static 类型变量。
     */
    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    /**
     * 决定使用哪个数据源之前需要把多个数据源的信息以及默认数据源信息配置好
     *
     * @param targetDataSources       目标数据源
     * @param defaultTargetDataSource 默认数据
     */
    public DynamicDataSource(Map<Object, Object> targetDataSources, DataSource defaultTargetDataSource) {
   
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }

    @Override
    protected Object determineCurrentLookupKey() {
   
        return CONTEXT_HOLDER.get();
    }

    public static void setDataSource(String dataSource) {
   
        CONTEXT
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值