Spring Boot + MyBatis-Plus 高并发读写分离实战

引言

在高并发场景下,单一数据库实例往往成为性能瓶颈。数据库读写分离通过将读操作和写操作分配到不同的数据库实例,有效缓解主库压力,提升系统吞吐量。MyBatis-Plus 作为一款强大的持久层框架,结合 Spring Boot 能够轻松实现读写分离。

一、读写分离的核心价值与挑战

1.1 高并发场景下的性能瓶颈

传统单库架构在QPS突破10万时,常面临以下问题:

  • 写入阻塞:大量INSERT/UPDATE操作导致锁竞争

  • 查询延迟:复杂报表分析占用CPU资源

  • 扩展困难:垂直扩容成本呈指数级增长

二、读写分离核心原理

2.1 基本概念

主库(Master):负责处理所有写操作(INSERT/UPDATE/DELETE),保证数据一致性

从库(Slave):负责处理读操作(SELECT),支持水平扩展

核心目标:通过主从复制保证数据同步,通过数据源路由实现读写分离

2.2 关键技术点

数据源路由:根据操作类型(读 / 写)动态切换数据源

主从复制:通过数据库自身机制(如 MySQL 的 Binlog 复制)保证主从数据一致

事务处理:写操作必须在主库执行,读操作可路由到从库

三、Spring Boot集成实战

3.1 环境搭建

Maven核心依赖:

java 复制代码
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.6.1</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.2</version>
</dependency>

3.2 数据源配置

java 复制代码
spring:
  datasource:
    dynamic:
      primary: master
      strict: false
      datasource:
        master:
          url: jdbc:mysql://master-host:3306/core?useSSL=false
          username: admin
          password: master@123
          driver-class-name: com.mysql.cj.jdbc.Driver
        slave1:
          url: jdbc:mysql://slave1-host:3306/core?useSSL=false
          username: readonly
          password: slave@123
          driver-class-name: com.mysql.cj.jdbc.Driver
        slave2:
          url: jdbc:mysql://slave2-host:3306/core?useSSL=false
          username: readonly
          password: slave@123
          driver-class-name: com.mysql.cj.jdbc.Driver

3.3 业务层实现

java 复制代码
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> {

    // 写操作自动路由到主库
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrder(Order order) {
        baseMapper.insert(order);
    }

    // 读操作指定从库
    @Override
    @DS("slave")
    public Order getOrderById(Long id) {
        return baseMapper.selectById(id);
    }

    // 负载均衡读库
    @DS("#slave")
    public List<Order> listOrders() {
        return baseMapper.selectList(null);
    }
}

3.4 配置动态数据源

java 复制代码
import com.baomidou.dynamic.datasource.processor.DynamicDataSourceProcessor;  
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.jdbc.datasource.DataSourceTransactionManager;  
@Configuration  
public class DataSourceConfig {  
    @Bean  
    @ConditionalOnMissingBean  
    public DynamicDataSourceProcessor dynamicDataSourceProcessor() {  
        return new DynamicDataSourceProcessor();  
    }  
    // 配置事务管理器(主库事务)  
    @Bean  
    public DataSourceTransactionManager transactionManager() {  
        return new DataSourceTransactionManager();  
    }  
}  

四、高阶功能实现

4.1 事务一致性保障

java 复制代码
@DS("master") // 强制走主库
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateStock(StockDTO dto) {
    stockMapper.deduct(dto);
    // 写入操作日志
    logMapper.insert(dto.getLog()); 
}

关键机制:

主库事务管理器优先

跨数据源事务需引入Seata等分布式事务框架

4.2 读写分离+分库分表

java 复制代码
dynamic:
  sharding:
    order:
      actualDataNodes: master.order_$->{0..9},slave1.order_$->{0..9}
      tableStrategy:
        standard:
          shardingColumn: user_id
          shardingAlgorithmName: mod10

结合分片算法实现水平扩展

五、生产级优化策略

5.1 连接池配置

java 复制代码
spring:
  datasource:
    dynamic:
      hikari:
        maxPoolSize: 50
        minIdle: 10
        connectionTimeout: 30000
        idleTimeout: 600000
        maxLifetime: 1800000

调优建议:

根据QPS计算连接数:maxPoolSize = (QPS × avg_query_time) / 1000

启用监控:集成Druid监控面板

5.2 数据同步监控

java 复制代码
@Scheduled(fixedRate = 60000)
public void checkReplicationDelay() {
    Long delay = slaveMapper.getReplicationDelay();
    if (delay > 5000) {
        alertService.send("从库延迟超过5秒!");
    }
}

5.3 故障转移机制

java 复制代码
@Bean
public MasterSlaveAutoRoutingPlugin routingPlugin() {
    MasterSlaveAutoRoutingPlugin plugin = new MasterSlaveAutoRoutingPlugin();
    plugin.setHealthCheckInterval(30000); // 30秒健康检查
    plugin.setSlaveRetryTimes(3); // 从库失败重试次数
    return plugin;
}

总结

通过 MyBatis-Plus 实现数据库读写分离,能够显著提升系统的读性能和可用性,是高并发场景下的必备技术。核心优势包括:

低侵入性:通过注解轻松实现数据源切换

灵活扩展:支持多从库负载均衡和动态数据源配置

事务安全:确保写操作在主库执行,保障数据一致性

相关推荐
小学鸡!10 分钟前
Spring Boot实现日志链路追踪
java·spring boot·后端
番茄Salad1 小时前
Spring Boot临时解决循环依赖注入问题
java·spring boot·spring cloud
摇滚侠4 小时前
Spring Boot 3零基础教程,WEB 开发 自定义静态资源目录 笔记31
spring boot·笔记·后端·spring
摇滚侠4 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 遍历 笔记40
spring boot·笔记·thymeleaf
橘子海全栈攻城狮5 小时前
【源码+文档+调试讲解】基于SpringBoot + Vue的知识产权管理系统 041
java·vue.js·人工智能·spring boot·后端·安全·spring
Json_6 小时前
学习springBoot框架-开发一个酒店管理系统,熟悉springboot框架语法~
java·spring boot·后端
kkkkk0211066 小时前
微服务学习笔记(黑马商城)
java·spring boot·spring·spring cloud·sentinel·mybatis·java-rabbitmq
冲鸭ONE6 小时前
新手搭建Spring Boot项目
spring boot·后端·程序员
数智顾问7 小时前
Flink ProcessFunction 与低层级 Join 实战手册:多流广告计费精确去重
java·spring boot·spring
Json____8 小时前
最近我用springBoot开发了一个二手交易管理系统,分享一下实现方式~
java·spring boot·后端