iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >springboot结合mysql主从来实现读写分离的方法示例
  • 677
分享到

springboot结合mysql主从来实现读写分离的方法示例

2024-04-02 19:04:59 677人浏览 薄情痞子
摘要

1.实现的功能     基于SpringBoot框架,application.yml配置多个数据源,使用aop以及AbstractRootingDat

1.实现的功能

    基于SpringBoot框架,application.yml配置多个数据源,使用aop以及AbstractRootingDataSource、ThreadLocal来实现多数据源切换,以实现读写分离。Mysql的主从数据库需要进行设置数据之间的同步。

2.代码实现

    application.properties中的配置


spring.datasource.druid.master.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.master.url=jdbc:mysql://127.0.0.1:3306/node2?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&autoReconnect=true&useSSL=false
spring.datasource.druid.master.username=root
spring.datasource.druid.master.passWord=123456
 
 
spring.datasource.druid.slave.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.slave.url=jdbc:mysql://127.0.0.1:3306/node1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&autoReconnect=true&useSSL=false
spring.datasource.druid.slave.username=root
spring.datasource.druid.slave.password=123456

写一个DataSourceConfig.java来注入两个bean


 @Bean
    @ConfigurationProperties("spring.datasource.druid.master")
    public DataSource masterDataSource() {
        logger.info("select master data source");
        return DruidDataSourceBuilder.create().build();
    }
 
    @Bean
    @ConfigurationProperties("spring.datasource.druid.slave")
    public DataSource slaveDataSource() {
        logger.info("select slave data source");
        return DruidDataSourceBuilder.create().build();
    }

写一个enum来标识有哪些数据源


public enum DBTypeEnum {
    MASTER, SLAVE;
}

然后写一个ThreadLocal本地线程的管理类,用于设置当前线程是那一个数据源


private static final ThreadLocal<DBTypeEnum> contextHolder = new ThreadLocal<>();
 
    private static final ThreadLocal<DBTypeEnum> contextHolder2 = ThreadLocal.withInitial(() -> DBTypeEnum.MASTER);
 
    public static void set(DBTypeEnum dbType) {
        contextHolder.set(dbType);
    }
 
    public static DBTypeEnum get() {
        return contextHolder.get();
    }
 
    public static void master() {
        set(DBTypeEnum.MASTER);
        logger.info("切换到master数据源");
    }
 
    public static void slave() {
        set(DBTypeEnum.SLAVE);
        logger.info("切换到slave数据源");
    }
 
    public static void cleanAll() {
        contextHolder.remove();
    }

然后写一个DynamicDataSource继承AbstractRootingDataSource,重写它的determineCurrentLookupKey方法。


public class DynamicDataSource extends AbstractRoutingDataSource {
    private Logger logger = LogManager.getLogger(DynamicDataSource.class);
 
    @Override
    protected Object determineCurrentLookupKey() {
        logger.info("此时数据源为{}", DBContextHolder.get());
        return DBContextHolder.get();
    }
}

最后写一个AOP来实现数据源切换


@Aspect
@Order(1)
@Component
public class DataSourceAop {
 
    private Logger logger = LogManager.getLogger(DataSourceAop.class);
 
    @Pointcut("(execution(* com.springboot.demo.service..*.select*(..)) " +
            "|| execution(* com.springboot.demo.service..*.find*(..)) " +
            "|| execution(* com.springboot.demo.service..*.get*(..)))")
    public void readPointcut() {
        logger.info("read only operate ,into slave db");
    }
 
    @Pointcut("execution(* com.springboot.demo.service..*.insert*(..)) " +
            "|| execution(* com.springboot.demo.service..*.update*(..)) " +
            "|| execution(* com.springboot.demo.service..*.delete*(..)) ")
    public void writePointcut() {
        logger.info("read or write operate ,into master db");
    }
 
    @Before("readPointcut()")
    public void read() {
        logger.info("read operate");
        DBContextHolder.slave();
    }
 
    @Before("writePointcut()")
    public void write() {
        logger.info("write operate");
        DBContextHolder.master();
    }
 
    @After("writePointcut(),readPointcut()")
    public void clean() {
        logger.info("dataSource cleanAll");
        DBContextHolder.cleanAll();
    }
}

注意:这里只是使用了偷懒的方法,对于service里面的select、get、find前缀的方法都使用从库,对于insert、update和delete方法都使用主库。

可以使用注解如下来进行优化:


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DataSource {
 
    @AliasFor("dataSource")
    DBTypeEnum value() default DBTypeEnum.MASTER;
 
    DBTypeEnum dataSource() default DBTypeEnum.MASTER;

}

使用此注解来放入到service方法上,


@DataSource(DBTypeEnum.SLAVE)

然后AOP方法修改为:


private static final String POINT = "execution (* com.springboot.demo.service.*.*(..))";
 
 
 @Around(POINT)
    public Object dataSourceAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        Object obj;
        Object target = joinPoint.getTarget();
        String methodName = joinPoint.getSignature().getName();
        Class clazz = target.getClass();
        Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameterTypes();
        boolean isDynamicDataSourceMethod = false;
        try {
            Method method = clazz.getMethod(methodName, parameterTypes);
            DataSources currentDataSource = null;
            if (method != null && method.isAnnotationPresent(DataSource.class)) {
                isDynamicDataSourceMethod = true;
                currentDataSource = method.getAnnotation(DataSource.class).value();
                DataSourceTypeManager.set(currentDataSource);
                log.info("DataSourceInterceptor Switch DataSource To {}",currentDataSource);
            }
            obj = joinPoint.proceed(args);
            if (isDynamicDataSourceMethod) {
                log.info("DataSourceInterceptor DataSource {} proceed",currentDataSource);
            }
        } finally {
            if (isDynamicDataSourceMethod) {
                DataSourceTypeManager.reset();
                log.info("DataSourceInterceptor Reset DataSource To {}",DataSourceTypeManager.get());
            }
        }
        return obj;
    }

到此这篇关于springboot结合mysql主从来实现读写分离的方法示例的文章就介绍到这了,更多相关springboot 读写分离内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: springboot结合mysql主从来实现读写分离的方法示例

本文链接: https://www.lsjlt.com/news/123894.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • springboot结合mysql主从来实现读写分离的方法示例
    1.实现的功能     基于springboot框架,application.yml配置多个数据源,使用AOP以及AbstractRootingDat...
    99+
    2024-04-02
  • springboot结合mysql主从来实现读写分离的方法
    这篇文章主要介绍springboot结合mysql主从来实现读写分离的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.实现的功能    基于springboot框架,applica...
    99+
    2023-06-14
  • SpringBoot环境-MySQL主从复制,读写分离的实现
    目录 概述 环境 主从复制 读写分离 概述  记录在MySQL数据库中主从复制以及SpringBoot环境操作MySQL数据库读写分离的实现步骤。  背景 :因为我们在对数据库进行操作时,如果读写操作都由一台数据库承担的话压...
    99+
    2023-09-06
    mysql 数据库 java linux
  • Django搭建MySQL主从实现读写分离
    目录一、MySQL主从搭建操作步骤二、Django实现读写分离自动指定一、MySQL主从搭建 主从配置原理: 主库写日志到 BinLog 从库开个 IO 线程读取...
    99+
    2024-04-02
  • mysql主从配置实现一主一从读写分离
    主从介绍Mysql主从又叫Replication、AB复制。简单讲就是A与B两台机器做主从后,在A上写数据,另外一台B也会跟着写数据,实现数据实时同步 mysql主从是基于binlog,主上需开启binlo...
    99+
    2024-04-02
  • SpringBoot整合sharding-jdbc实现分库分表与读写分离的示例
    目录一、前言二、数据库表准备三、整合四、docker-compose部署mysql主从五、本文案例demo源码一、前言 本文将基于以下环境整合sharding-jdbc实现分库分表与...
    99+
    2024-04-02
  • springboot多数据源配合docker部署mysql主从实现读写分离效果
    目录一、使用docker部署mysql主从 实现主从复制二、springboot项目多数据源配置,实现读写分离一、使用docker部署mysql主从 实现主从复制 此次使用的是win...
    99+
    2024-04-02
  • MySQL高可用实现:主从结构下ProxySQL中的读写分离
    原文: http://www.enmotech.com/web/detail/1/714/1.html ( 复制链接,打开浏览器即可查看原文 )  墨墨导读:Pro...
    99+
    2024-04-02
  • Mycat中间件实现Mysql主从读写分离
    环境规划: IP地址 主机名 角色 备注 10.4.132.50 k8s01 mycat,master 10.4.132.42 k8s02 slave ...
    99+
    2024-04-02
  • SpringBoot+MyBatis+AOP实现读写分离的示例代码
    目录一、 MySQL 读写分离1.1、如何实现 MySQL 的读写分离? 1.2、MySQL 主从复制原理?1.3、MySQL 主从同步延时问题(精华)二、SpringBo...
    99+
    2024-04-02
  • MyCat怎么实现MySQL一主两从读写分离
    这篇文章主要介绍“MyCat怎么实现MySQL一主两从读写分离”,在日常操作中,相信很多人在MyCat怎么实现MySQL一主两从读写分离问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大...
    99+
    2024-04-02
  • MyCat如何实现MySQL双主一从读写分离
    这篇文章给大家分享的是有关MyCat如何实现MySQL双主一从读写分离的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1)配置server.xml<user nam...
    99+
    2024-04-02
  • mysql主从复制读写分离的配置方法详解
    一、说明 前面我们说了mysql的安装配置,mysql语句使用以及备份恢复mysql数据;本次要介绍的是mysql的主从复制,读写分离;及高可用MHA; 环境如下: master:CentOS7_x64...
    99+
    2024-04-02
  • Mysql主从复制,读写分离,分表分库策略与实践的示例分析
    本篇文章给大家分享的是有关Mysql主从复制,读写分离,分表分库策略与实践的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、MySQ...
    99+
    2024-04-02
  • MySQL中怎么实现主从复制及读写分离
    MySQL中怎么实现主从复制及读写分离?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、相关概述主从复制:主数据库(Master)发送更新事件到从数据库(Slave),从数...
    99+
    2023-06-14
  • Linux如何使用 MyCat 实现 MySQL 主从读写分离
    目录Linux-使用 MyCat 实现 MySQL 主从读写分离 一、MySQL 读写分离1、MySQL 读写分离的概述2、读写分离工作原理3、为什么要读写分离3、实现读写分离的方式...
    99+
    2024-04-02
  • MySQL中如何实现主从复制与读写分离
    MySQL中如何实现主从复制与读写分离,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1,mysql的配置CentOS 5.x,6.0编译安装N...
    99+
    2024-04-02
  • 怎么在Mysql中实现主从复制与读写分离
    这期内容当中小编将会给大家带来有关怎么在Mysql中实现主从复制与读写分离,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。文章思维导图为什么使用主从复制、读写分离主从复制、读写分离一般是一起使用的。目的很简...
    99+
    2023-06-14
  • mysql读写分离实现的方法是什么
    MySQL读写分离是通过将读操作和写操作分别分配到不同的MySQL实例上来实现的。 常见的实现方法有以下两种: 通过MySQL代...
    99+
    2024-04-09
    mysql
  • 原来这就是大厂的MySQL主从复制及读写分离方案
    1 单机 =》集群 随着数据量的增大,读写并发的增加,系统可用性要求的提升,单机 MySQL 出现危机: 容量问题,难以扩容,考虑数据库拆分、分库分表 读写压力,QPS 过大,特别是分析类需求会影响到业务事务,考虑多机集群、主从复制 高可...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作