iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >springboot多数据源配合docker部署mysql主从实现读写分离效果
  • 810
分享到

springboot多数据源配合docker部署mysql主从实现读写分离效果

2024-04-02 19:04:59 810人浏览 泡泡鱼
摘要

目录一、使用Docker部署Mysql主从 实现主从复制二、SpringBoot项目多数据源配置,实现读写分离一、使用docker部署mysql主从 实现主从复制 此次使用的是win

一、使用docker部署mysql主从 实现主从复制

此次使用的是windows版本docker,mysql版本是5.7

1、使用docker获取mysql镜像


docker pull mysql:5.7.23 #拉取镜像文件

docker images #查看镜像文件

2、使用docker运行mysql master


docker run --name mysql-master --privileged=true -v F:\dockerV\mysql:/var/lib/mysql -p 3307:3306 -e MYSQL_ROOT_PASSWord=654321 -d mysql:5.7.23
  • --name 容器名称mysql-master
  • --privileged 指定了当前容器是否真正的具有root权限,所谓的root权限是指具有宿主机的root权限,而不仅仅只是在容器内部有root权限
  • -v 将系统的F:\dockerV\mysql挂载到容器的/var/lib/mysql,注意是将宿主机 挂载到 容器内部,而不是将容器内部挂载到宿主机
  • -p 表示宿主机上的某个端口映射到docker容器内的某个端口,这里也就是将宿主机的3307端口映射到容器内部的3306端口
  • -e 表示指定当前容器运行的环境变量,该变量一般在容器内部程序的配置文件中使用,而在外部运行容器指定该参数。这里的MYSQL_ROOT_PASSWORD表示容器内部的MySQL的启动密码
  • -d 后台运行,镜像文件为mysql:5.7.23

接下来进入容器内部,修改配置,使其作为mysql master运行


docker exec -it mysql-master bash #进入容器内部

配置mysql master,修改mysql.cnf

使用vim修改mysql.cnf,没有安装vim会提示bash: vi: command not found 则需要安装vim


apt-get install vim

apt-get update

apt-get install vim

vim mysqld.cnf #修改cnf文件,添加 server-id 表示master服务标识,同一局域网内注意要唯一 和 log-bin=mysql-bin 开启二进制日志功能,可以随便取,用来完成主从复制

修改完成mysql的配置后,需要重启服务生效


service MySQL restart # 重启mysql服务时会使得docker容器停止,我们还需要docker start mysql-master启动容器

docker start mysql-master #启动容器

连接mysql客户端,创建用来完成主从复制的账号


mysql -uroot -p654321 #连接mysql

为从服务器创建一个可以用来操作master服务器的账户,也就是创建一个专门用来复制binlog的账号,并且赋予该账号复制权限,其命令如下


grant replication slave on *.* to 'slaveaccount'@'%' identified by '654321'; #账号slaveaccount 密码654321

flush privileges; #刷新用户权限表

show master status #查看mysql master的状态

记录下上的position和file 在创建MySQL slave配置时会用到

到这里mysql master 已经配置完成了

3、使用docker运行mysql slave


docker run --name mysql-slave --privileged=true -v F:\dockerV\mysql-slave:/var/lib/mysql -p 3308:3306 --link mysql-master:master -e MYSQL_ROOT_PASSWORD=654321 -d mysql:5.7.23

mysql slave 的参数主要和master有两点不同

  • 所映射的宿主机的端口号不能与master容器相同,因为其已经被master容器占用;
  • 必须加上--link参数,其后指定了当前容器所要连接的容器,mysql-master表示所要连接的容器的名称,master表示为该容器起的一个别名,通俗来讲,就是slave容器通过这两个名称都可以访问到master容器。这么做的原因在于,如果master与slave不在同一个docker network中,那么这两个容器相互之间是没法访问的。

docker exec -it mysql-slave /bin/bash #进入mysql salve容器

vim mysqld.cnf #修改cnf文件,添加 server-id 表示slave服务标识,如果此salve需要作为其他mysql的主,那么就需要配置log-bin=mysql-bin

service MySQL restart # 重启mysql服务时会使得docker容器停止,我们还需要docker start mysql-slave启动容器

docker start mysql-master #启动容器

mysql -uroot -proot #连接mysql服务

配置mysql slave 使其以slave模式运行


change master to master_host='172.17.0.2', master_user='slaveaccount', master_password='654321', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=2272, master_connect_retry=30;

注意:这一步主要在slave是配置master的信息,包括 master的 地址、端口、账号、密码、log文件、log文件偏移量、重试。下面介绍这些参数值从何获取

获取master_host,使用docker inspect mysql-master查看master容器元数据。其中 IPAdress是master_host

  • 获取master_port,是运行master映射容器内部的端口,这里就是3306
  • 获取master_user和master_password,是第一步中在master中创建的slave账号
  • 获取master_log_file和master_log_pos,是配置master中最后一步使用show master status获取的文件和偏移量
  • 获取master_connect_retry,是slave重试连接master动作前的休眠时间,单位s,默认60s

start slave; #以slave模式运行

show salve status \G; #查看slave的状态

可以看到,Slave_IO_Running:YES和Slave_SQL_Running:YES 证明此时主从复制已经就绪,slave配置到此完成

4、验证主从复制效果

  • 这里我们在连接master,并创建一张表,添加数据,在从库查看数据是否同步。
  • 在主库创建数据,并在从库查看数据是否同步成功。

mysql> create database test;
Query OK, 1 row affected (0.01 sec)

mysql> use test;
Database changed

mysql> create table t_user(id bigint, name varchar(255));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t_user(id, name) value (1, 'cgg');
Query OK, 1 row affected (0.01 sec)
mysql> select * from test.t_user;
+------+------+
| id   | name |
+------+------+
|    1 | cgg |
+------+------+
1 row in set (0.00 sec)

5、mysql主从复制原理

  • 主库db的更新事件(update、insert、delete)被写到binlog
  • 主库创建一个binlog dump thread,把binlog的内容发送到从库
  • 从库启动并发起连接,连接到主库
  • 从库启动之后,创建一个I/O线程,读取主库传过来的binlog内容并写入到relay log
  • 从库启动之后,创建一个SQL线程,从relay log里面读取内容,从Exec_Master_Log_Pos位置开始执行读取到的更新事件,将更新内容写入到slave的db

二、springboot项目多数据源配置,实现读写分离

1、主从多数据源配置

yml配置


server:
  port: 8888
  servlet:
    encoding:
      charset: UTF-8
      force: true
      enabled: true
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://127.0.0.1:3307/test?serverTimezone=GMT%2B8&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&useSSL=false
    username: root
    password: 654321
slave:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://127.0.0.1:3308/test?serverTimezone=GMT%2B8&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&useSSL=false
    username: root
    password: 654321

数据源配置



@Configuration
@EnableTransactionManagement
public class DynamicDataSourceConfig {


    @Bean(name = "slaveDatasource")
    @ConfigurationProperties(prefix = "slave.datasource")
    public DataSource dbSlave() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "dataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dbMaster() {
        return DruidDataSourceBuilder.create().build();
    }


    @Bean
    @Primary
    public DataSource multipleDataSource(@Qualifier("dataSource") DataSource db,
                                         @Qualifier("slaveDatasource") DataSource slaveDatasource) {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        Map<Object, Object> targetDataSources = new HashMap<>(16);
        targetDataSources.put("dataSource", db);
        targetDataSources.put("slaveDatasource", slaveDatasource);
        dynamicDataSource.setTargetDataSources(targetDataSources);
        //设置默认数据源为从库,如果写操作业务多,可以默认设置为主库
        dynamicDataSource.setDefaultTargetDataSource(slaveDatasource);
        return dynamicDataSource;
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        mybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(multipleDataSource(dbSlave(), dbMaster()));
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        sqlSessionFactory.setConfiguration(configuration);
        sqlSessionFactory.setMapperLocations((new PathMatchingResourcePatternResolver()).getResources(DEFAULT_MAPPER_LOCATION));
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setOverflow(false);
        paginationInterceptor.setLimit(-1);
        paginationInterceptor.setCountSqlParser(tenantSqlParserCountOptimize());
        Interceptor[] plugins = new Interceptor[]{new ShardTableInterceptor(), paginationInterceptor};
        sqlSessionFactory.setPlugins(plugins);
        return sqlSessionFactory.getObject();
    }

}


@Slf4j
public class DynamicDataSource  extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DbContextHolder.getDbType();
    }
}

2、配置切面控制主从数据源切换、读从库写主库,实现读写分离

aop切面



@Component
@Order(value = -100)
@Slf4j
@Aspect
public class DataSourceSwitchAspect {

    //master 包下的操作都是操作主库业务
    @Pointcut("execution(* com.master..*.*(..))")
    private void db1Aspect() {
    }

    //slave 包下的操作都是操作从库业务
    @Pointcut("execution(* com.slave.*.*(..))")
    private void db2Aspect() {
    }


    @Before("db1Aspect()")
    public void dbMaster() {
        log.debug("切换到Master 数据源...");
        DbContextHolder.setDbType("dataSource");
    }

    @Before("db2Aspect()")
    public void dbSlave() {
        log.debug("切换到Slave 数据源...");
        DbContextHolder.setDbType("slaveDatasource");
    }
}



public class DbContextHolder {
    private static final ThreadLocal contextHolder = new ThreadLocal<>();
    
    public static void setDbType(String dbType) {
        contextHolder.set(dbType);
    }

    
    public static String getDbType() {
        return (String) contextHolder.get();
    }

    
    public static void clearDbType() {
        contextHolder.remove();
    }
}

3、验证读写分离效果

使用接口调用不同接口,切点会自动切换数据源,这里写库接口只会操作主库,读库接口会操作从库。实现读写分离

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

您可能感兴趣的文档:

--结束END--

本文标题: springboot多数据源配合docker部署mysql主从实现读写分离效果

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

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

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

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

下载Word文档
猜你喜欢
  • springboot多数据源配合docker部署mysql主从实现读写分离效果
    目录一、使用docker部署mysql主从 实现主从复制二、springboot项目多数据源配置,实现读写分离一、使用docker部署mysql主从 实现主从复制 此次使用的是win...
    99+
    2024-04-02
  • springboot结合mysql主从来实现读写分离的方法
    这篇文章主要介绍springboot结合mysql主从来实现读写分离的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.实现的功能    基于springboot框架,applica...
    99+
    2023-06-14
  • mysql主从配置实现一主一从读写分离
    主从介绍Mysql主从又叫Replication、AB复制。简单讲就是A与B两台机器做主从后,在A上写数据,另外一台B也会跟着写数据,实现数据实时同步 mysql主从是基于binlog,主上需开启binlo...
    99+
    2024-04-02
  • springboot结合mysql主从来实现读写分离的方法示例
    1.实现的功能     基于springboot框架,application.yml配置多个数据源,使用AOP以及AbstractRootingDat...
    99+
    2024-04-02
  • SpringBoot环境-MySQL主从复制,读写分离的实现
    目录 概述 环境 主从复制 读写分离 概述  记录在MySQL数据库中主从复制以及SpringBoot环境操作MySQL数据库读写分离的实现步骤。  背景 :因为我们在对数据库进行操作时,如果读写操作都由一台数据库承担的话压...
    99+
    2023-09-06
    mysql 数据库 java linux
  • Spring如何实现多数据源读写分离
    这篇文章主要介绍“Spring如何实现多数据源读写分离”,在日常操作中,相信很多人在Spring如何实现多数据源读写分离问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Spri...
    99+
    2024-04-02
  • 利用MySQL主从配置实现读写分离减轻数据库压力
    大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够。到了数据业务层、数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢失的话...
    99+
    2024-04-02
  • MySQL数据库的主从同步配置与读写分离
    使用mysql主从复制的好处有: 1、采用主从服务器这种架构,稳定性得以提升。如果主服务器发生故障,我们可以使用从服务器来提供服务。 2、在主从服务器上分开处理用户的请求,可以提升数据处理效率。 3、将主服...
    99+
    2024-04-02
  • Mysql数据库的主从复制与读写分离怎么实现
    这篇文章主要介绍“Mysql数据库的主从复制与读写分离怎么实现”,在日常操作中,相信很多人在Mysql数据库的主从复制与读写分离怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Mysql数据库的主从复制...
    99+
    2023-06-21
  • Spring+Mybatis 实现aop数据库读写分离与多数据库源配置操作
    在数据库层面大都采用读写分离技术,就是一个Master数据库,多个Slave数据库。Master库负责数据更新和实时数据查询,Slave库当然负责非实时数据查询。因为在实际的应用中,数据库都是读多写少(读取数据的频率高,更新数据的频率相对较...
    99+
    2023-05-31
    spring mybatis 读写分离
  • SpringBoot多数据源读写分离的自定义配置问题及解决方法
    目录针对device库我们先创建一个数据库连接配置类在类中添加配置文件中的读写数据源创建返回SqlSessionFactory的Bean创建SqlSessionTemplate的Be...
    99+
    2024-04-02
  • SpringBoot整合mysql、postgres、sqlserver实现多数据源配置案例
            分享一下近期处理的一个小demo,关于配置多数据源实现不同服务之间的数据推送和数据治理。第一次接触到pg库和sqlserver一头雾水,选择了JDBC+mybatis-plus的方式去链接。 首先要引入以下依赖 org.sp...
    99+
    2023-10-07
    java mybatis
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作