首页 > 数据库 >数据库读写分离分案

数据库读写分离分案

时间:2024-03-25 15:30:29浏览次数:20  
标签:jdbc 数据源 读写 com spring 分案 true 数据库

环境:MySQL主从数据库。如需要搭建可参考上一篇文章:MySQL主从数据库简单搭建

数据库使用主从可确保数据一致性,示例是基于一个完整的项目之上做了一些修改,为测试效果直接连接了两个非主从配置的数据库,其中只有测试的数据表内容不同其余内容全部相同。

方案参考:MySQL读写分离的三种实现方案

一、应用层(动态数据源切换)实现

优点: 1、不需要引入中间件; 2、 理论上支持任何数据库;
缺点: 1、侵入性强; 2、 根据具体的 Service 方法是否会操作数据,注入不同的数据源;

1、引入动态数据源依赖

<dependency>
	  <groupId>com.baomidou</groupId>
      <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
      <version>2.5.5</version>
</dependency>

2、配置文件修改

spring:
  datasource:
    dynamic:
      primary: master
      strict: false
      datasource:
        master:
          type: com.alibaba.druid.pool.DruidDataSource
          url: jdbc:mysql://192.168.100.205:3306/mydb?serverTimezone=GMT&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
          username: root
          password: '123456'
          driver-class-name: com.mysql.cj.jdbc.Driver
          initial-size: 5 # 初始连接数
          max-active: 50 # 最大连接数
          min-idle: 5 # 最小空闲连接数
          validation-query: SELECT 1 # 验证连接是否有效的 SQL 查询语句
          test-while-idle: true # 空闲时验证连接是否有效
          test-on-borrow: false # 获取连接时验证连接是否有效
          test-on-return: false # 归还连接时验证连接是否有效
          time-between-eviction-runs-millis: 60000 # 连接回收的时间间隔
          min-evictable-idle-time-millis: 300000 # 连接在池中最小生存的时间
        slave_1:
          type: com.alibaba.druid.pool.DruidDataSource
          url: jdbc:mysql://192.168.100.5:3306/mydb?serverTimezone=GMT&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
          username: root
          password: '123456'
          driver-class-name: com.mysql.cj.jdbc.Driver
          initial-size: 5
          max-active: 50
          min-idle: 5
          validation-query: SELECT 1
          test-while-idle: true
          test-on-borrow: false
          test-on-return: false
          time-between-eviction-runs-millis: 60000
          min-evictable-idle-time-millis: 300000

3、ServiceImpl相关实现中添加注解,指定切换从数据库

@Override
public void getById() {
	userMapper.getCount();
}

@DS("slave")
@Override
public void getById2() {
	userMapper.getCount2();
}

由于在数据源中配置了primary: master,默认操作都会从主库执行,使用注解@DS切换数据源,此注解也可直接用于类文件上,同时存在方法注解优先于类上注解。

4、测试验证

两个方法的查询语句一样,但设置两个测试数据库查询的表的内容有所不同,如果能查出对应的值说明读写分离成功。
项目启动成功会打印日志:
项目启动成功打印日志

5、遇到问题

项目启动失败
1、如果启动失败,可能是由于修改数据库配置,部分配置文件不匹配,需要注释掉。
比如示例项目中有未修改之前的配置类。数据库配置类
2、SpringBoot 启动时自动配置数据库信息导致启动失败,项目启动类添加注解。

@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)

因为 DruidDataSourceAutoConfigure 在 DynamicDataSourceAutoConfiguration 之前会注入一个 DataSourceWrapper,会在原生的 spring.datasource 下找 url,username,password 信息,在启动类上排除掉自动配置类即可。
项目启动补充注解

二、ShardingSphere-jdbc 实现

优点: 1、做SQL解析,自动实现读写分离; 2、 将事务都管理起来;
缺点: 1、存在侵入性(需要配置在代码中);

ShardingSphere参考文档:ShardingSphere 文档
ShardingSphere源码:ShardingSphere源码

1、引入ShardingSphere的Jar包依赖

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.0.0-RC1</version>
</dependency>

2、配置文件修改

spring:
  shardingsphere:
    # 数据源相关配置
    datasource:
      # 数据源名称
      names: master,s1
      # MySQL master数据源
      master:
        # 数据库连接池
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.100.205:3306/shardingsphere_demo?serverTimezone=GMT&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
        username: root
        password: 123456
      # slave数据源
      s1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.100.5:3306/shardingsphere_demo?serverTimezone=GMT&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
        username: root
        password: 123456
    masterslave:
      load-balance-algorithm-type: round_robin
      name: ms
      master-data-source-name: master
      slave-data-source-names: s1

    # 其他属性
    props:
      # 开启SQL显示
      sql.show: true

3、测试验证

写好测试代码,简单的数据库操作查询、新增即可,主要是为了测试查询走从库,对数据库操作走主库。

启动成功,控制台会打印初始化了两个数据库:
启动成功控制台输出执行查询时,控制台输出:
在这里插入图片描述执行新增时,控制台输出:
在这里插入图片描述

4、遇到问题

1、如果是在原有项目上改数据库配置,记得将nacos中原有数据库相关配置注释掉,原有项目中数据库配置类相关内容也要注释掉。

2、最初使用的是 4.1.1 版本,启动服务总是报错启动失败。
pom依赖

Caused by: java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
	at org.springframework.util.Assert.notNull(Assert.java:201)
	at org.mybatis.spring.support.SqlSessionDaoSupport.checkDaoConfig(SqlSessionDaoSupport.java:122)
	at org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:73)
	at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
	... 49 common frames omitted

上网找解决方案,最终处理是将版本降低了。
pom依赖
版本降低之后启动还有报错,根据报错信息又加了一个配置,最终启动成功。

spring:
  main:
    allow-bean-definition-overriding: true

参考推荐:【MySQL系列】真香!基于ShardingSphere-JDBC的MySQL读写分离

标签:jdbc,数据源,读写,com,spring,分案,true,数据库
From: https://blog.csdn.net/qq_40001822/article/details/136735245

相关文章

  • 达梦数据库如何解除主从关系
    环境:OS:Centos7DB:DMV8 1.停掉dmwatcher并删除服务[root@host02root]#systemctlstopDmWatcherServiceGRP1[root@host02root]#cd/dmdbms/product/script/root[root@host02root]#./dm_service_uninstaller.sh-nDmWatcherServiceGRP1 2.删除实时归档[dmdba@host......
  • 三、 mariadb数据库用户管理
    1)查询有哪些用户MariaDB>selectuser,hostfrommysql.user;+------+-----------+|user|host   |+------+-----------+|root|127.0.0.1||root|::1   ||   |localhost||root|localhost||   |oldboy  ||root|oldb......
  • 瀚高数据库 select-sql常用函数
    瀚高数据库select-sql常用函数1、字符串拼接||语法string||string示例'post'||'gresql'--返回postgresql2、字符串的长度length()语法length(string)示例length('odoo')--返回43、模式匹配like语法stringlikepattern示例’abc’like’abc’--返回true’abc’li......
  • SQLYOG连接数据库时报错1251
    报错图片报错原因:主要是由于mysql8以前的加密规则与mysql8以后的存在差异,一些版本旧的客户端和服务端版本差别太大!解决办法:1.修改加密规则(注意引号为英文单引号,后面结尾的分号必须带上,@符号和引号之间无空格,下同)ALTERUSER'root'@'localhost'IDENTIFIEDBY'passwor......
  • 截取适合数据库长度的字符串
    importjava.nio.charset.StandardCharsets;publicclassTools{publicstaticvoidmain(String[]args){System.out.println(splitString("[计算费用应judnsdjwddqwhwqdwdqhwdqhwqhqwihq就得花洒uhuqwduhqwudquwhuqdwuhdqwqdw请重新计算;",128));}......
  • 达梦数据库主从切换(takeover)
    环境:OS:Centos7DB:V8 1.手工执行监控器[dmdba@host02DAMENG]$dmmonitor/dmdbms/data/DAMENG/dmmonitor.iniloginusername:sysdbapassword:[monitor]2024-03-2509:54:55:Logindmmonitorsuccess!choosetakeoverGRP1Group(grp1)hasactiveprimary......
  • 常用命令--数据库备份--mysqdump
    常用命令--数据库备份--mysqdump常用选项mysqldump是MySQL数据库的一个重要工具,用于创建数据库的逻辑备份。以下是mysqldump的一些常用选项及其功能:1.-uusername或--user=username:指定连接MySQL服务器的用户名。2.-p或--password:提示输入密码。也可以直接跟在-u......
  • 为什么连接数据库的端口号与配置文件中的端口号不一致?
    为什么连接数据库的端口号与配置文件中的端口号不一致?背景介绍:在安装openGauss3.0数据库时,发现配置文件中写的端口号是5432,但是数据库连接时,执行gsql--dpostgres-p5432提示错误,无法连接到数据库。报错内容:[omm@hostname]$gsql-dpostgres-p5432failedtoconn......
  • cmd窗口远程连接mysql数据库命令
    注意点:电脑需要先安装好mysql数据库(不等同于安装好Navicat工具,是要安装好MySQL数据库)1、同时点击win+R,输入cmd之后点击回车,进入cmd窗口;2、直接在命令行中输入mysql-h数据库ip地址-P端口号-u用户名-p比如:mysql-h192.168.5.116-P3306-uroot-p3、点击回车,会出......
  • 【转载】基于Ado.Net多个关系型数据库DbHelper封装
    主要是记录一下,后续有用的时候再翻看。publicclassDbHelper{privatereadonlyDataBase_dataBase;publicDbHelper(DataBasedataBase){_dataBase=dataBase;}publicDataBaseGetDataBase(){......