SpringBoot2.x微服务通过AOP方式实现读写分离

x33g5p2x  于2021-09-24 转载在 Spring  
字(2.6k)|赞(0)|评价(0)|浏览(384)

MySQL一主多从请参考:https://blog.csdn.net/MadLifeBin/article/details/119067776

SpringBoot2.x+shardingsphere-jdbc5.0.0-alpha搭建读写分离请参考:https://blog.csdn.net/MadLifeBin/article/details/119360082

主要思路

实现读写分离主要通过两种方式实现。

应用层

  • Spring AOP + SpringBoot 动态数据源
  • Shading-jdbc

中间件

  • MyCat 阿里云开源
  • mysql-proxy 官方
  • Amoeba for MySQL
  • 360 Atlas 奇虎360

中间件方式,各有千秋。

应用层主要实现

核心代码展示

@Aspect
@Component
public class DataSourceAop {

    @Pointcut("!@annotation(cn.pengld.annotation.Master) " +
            "&& (execution(* cn.pengld.mapper.*.select*(..)) " +
            "|| execution(* cn.pengld.mapper.*.get*(..)))" +
            "|| execution(* cn.pengld.mapper.*.list*(..)))")
    public void readPointcut() {

    }

    @Pointcut("@annotation(cn.pengld.annotation.Master) " +
            "|| execution(* cn.pengld.mapper.*.insert*(..)) " +
            "|| execution(* cn.pengld.mapper.*.add*(..)) " +
            "|| execution(* cn.pengld.mapper.*.update*(..)) " +
            "|| execution(* cn.pengld.mapper.*.edit*(..)) " +
            "|| execution(* cn.pengld.mapper.*.delete*(..)) " +
            "|| execution(* cn.pengld.mapper.*.remove*(..))")
    public void writePointcut() {

    }
    @Before("readPointcut()")
    public void read() {
        DBContextHolder.slave();
    }
    @Before("writePointcut()")
    public void write() {
        DBContextHolder.master();
    }

}
@Bean
    public DataSource masterDataSource() {
        return DataSourceBuilder.create()
                .driverClassName(driverClassName)
                .url(masterDataSourceUrl)
                .username(masterDataSourceUsername)
                .password(masterDataSourcePassword)
                .build();
    }

    @Bean
    public DataSource slave1DataSource() {
        return DataSourceBuilder.create()
                .driverClassName(driverClassName)
                .url(slave1DataSourceUrl)
                .username(slave1DataSourceUsername)
                .password(slave1DataSourcePassword)
                .build();
    }

    @Bean
    public DataSource slave2DataSource() {
        return DataSourceBuilder.create()
                .driverClassName(driverClassName)
                .url(slave2DataSourceUrl)
                .username(slave2DataSourceUsername)
                .password(slave2DataSourcePassword)
                .build();
    }

    @Bean
    public DataSource myRoutingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
                                          @Qualifier("slave1DataSource") DataSource slave1DataSource,
                                          @Qualifier("slave2DataSource") DataSource slave2DataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DBTypeEnum.MASTER, masterDataSource);
        targetDataSources.put(DBTypeEnum.SLAVE1, slave1DataSource);
        targetDataSources.put(DBTypeEnum.SLAVE2, slave2DataSource);
        MyRoutingDataSource myRoutingDataSource = new MyRoutingDataSource();
        myRoutingDataSource.setDefaultTargetDataSource(masterDataSource);
        myRoutingDataSource.setTargetDataSources(targetDataSources);
        return myRoutingDataSource;
    }

代码参考地址:https://gitee.com/pengld-demo/read-write-separate-demo

相关文章

微信公众号

最新文章

更多