目录一、使用Docker部署Mysql主从 实现主从复制二、SpringBoot项目多数据源配置,实现读写分离一、使用docker部署mysql主从 实现主从复制 此次使用的是win
此次使用的是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
接下来进入容器内部,修改配置,使其作为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有两点不同
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
start slave; #以slave模式运行
show salve status \G; #查看slave的状态
可以看到,Slave_IO_Running:YES和Slave_SQL_Running:YES 证明此时主从复制已经就绪,slave配置到此完成
4、验证主从复制效果
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主从复制原理
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://lsjlt.com/news/136523.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-10-23
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0