Mysql读写分离实例

吐槽:前天刚加完MQ,这回加读写分离。我也是醉了,但是弄完之后,就发现,似乎没我想的那么复杂,真的!另外,昨天试了一下用swagger编写API文档,太方便了,加上Mock service测试。这两天都好忙啊,忙着优化项目,忙着写接口,不过,再忙的日子,也得写总结!今天,主要是记录一下,往项目中加读写分离的过程。

1,mysql数据库安装,不说了。主从配置,也不说了。有需要的,请宝宝吃饭,宝宝手把手教!

2,宏观描述一下过程:在访问service方法前,通过AOP做出判断(以方法名:嘿嘿,命名规范哈)如果是以query、find、get等读操作打头的,就走从库(读库),其他的,则走主库(写库)

3、具体实施

3.1,首先是定义动态数据源,通过继承实现Spring提供的AbstractRoutingDataSource抽象类的determineCurrentLookupKey方法:

 

public class DynamicDataSource extends AbstractRoutingDataSource {

    /**
     * 定义动态数据源
     * @return
     */
    @Override
    protected Object determineCurrentLookupKey() {
        //返回当前线程中的数据源
        return DynamicDataSourceHolder.getDataSourceKey();
    }
}
public class DynamicDataSourceHolder {

    //写库数据源key值
    private static final String MASTER="master";
    //读库数据源key值
    private static final String SLAVE="slave";

    //使用threadlocal记录当前线程的数据源
    private static final ThreadLocal<String> holder=new ThreadLocal<>();

    //设置数据源
    public static void putDataSourceKey(String key){
        holder.set(key);
    }

    //获取数据源
    public static String getDataSourceKey(){
        return holder.get();
    }

    public static void markMaster(){
        putDataSourceKey(MASTER);
    }

    public static void markSlave(){
        putDataSourceKey(SLAVE);
    }
}

3.2,编写AOP织入的切面

 

 

public class DataSourceAspect {

    /**
     * 进入service方法之前执行
     * @param joinpoint 切面对象
     */
    public void before(JoinPoint joinpoint){
        //获取当前执行方法名
        String methodName=joinpoint.getSignature().getName();
        //分别标记读、写库
        if(isSlave(methodName)){
            DynamicDataSourceHolder.markSlave();
        }else{
            DynamicDataSourceHolder.markMaster();
        }
    }

    /**
     * 是否是从库(读库)
     * @param methodName 访问的方法名称
     * @return 如果是从库,返回true
     */
    private boolean isSlave(String methodName){
        return StringUtils.startsWithAny(methodName,"query","find","get");
    }

}


3.3,配置数据源

 

首先,是在db.properties文件中,配置两个数据源(可能会有多个从库,这里以主从分别为一个说明),分别为写库和读库

其次,为两个数据源配置连接池

然后,定义DataSource

 

<bean id="dataSource" class="DynamicData.DynamicDataSource">
        <!--配置多个数据源-->
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry key="master" value-ref="masterDataSource"/>
                <entry key="slave" value-ref="slaveDataSource"/>
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="masterDataSource"/>
</bean>


3.4,定义切面

 

事务什么的,早就配好了,这里略过,主要是说关于读写分离的要点。

 

<!--定义AOP切面处理器-->
    <bean class="DynamicData.DataSourceAspect" id="dataSourceAspect"/>

    <!-- 切面 -->
    <aop:config>
        <!-- 定义切面,所有的service的所有方法——读写 -->
        <aop:pointcut id="txPointcut"
                      expression="execution(* *.service.*.*(..))" />

        <!--事务传播策略-->
        <aop:advisor advice-ref="txAdvice"
                     pointcut="execution(* *.service.*.*(..))" />
        <!-- 将切面应用到自定义的切面处理器上,-9999保证该切面优先级最高执行 -->
        <aop:aspect ref="dataSourceAspect" order="-9999">
            <aop:before method="before" pointcut-ref="txPointcut" />
        </aop:aspect>
    </aop:config>


4,总结

 

这样子,就配好了(嘿嘿,但愿我没有忘记什么,这两天脑袋里东西有点多) 读写分离,配好了。值得一说的是,虽然没有过多的说mysql的安装配置,但是,对于主从的存储引擎配置,应该注意。分别为主从数据库,配置相应的存储引擎!


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值