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 实现数据库读写分离,能够显著提升系统的读性能和可用性,是高并发场景下的必备技术。核心优势包括:

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

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

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

相关推荐
一 乐1 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
期待のcode4 小时前
前后端分离项目 Springboot+vue 在云服务器上的部署
服务器·vue.js·spring boot
ProgramHan5 小时前
Spring Boot 3.2 新特性:虚拟线程的落地实践
java·jvm·spring boot
源码获取_wx:Fegn08956 小时前
基于 vue智慧养老院系统
开发语言·前端·javascript·vue.js·spring boot·后端·课程设计
张较瘦_6 小时前
SpringBoot3 | MyBatis-Plus 搞定宠物管理:从0到1实现增删改查
mybatis·宠物
毕设源码_郑学姐6 小时前
计算机毕业设计springboot基于HTML5的酒店预订管理系统 基于Spring Boot框架的HTML5酒店预订管理平台设计与实现 HTML5与Spring Boot技术驱动的酒店预订管理系统开
spring boot·后端·课程设计
不吃香菜学java6 小时前
spring-依赖注入
java·spring boot·后端·spring·ssm
南部余额6 小时前
Spring Boot 整合 MinIO:封装常用工具类简化文件上传、启动项目初始化桶
java·spring boot·后端·文件上传·工具类·minio·minioutils
QQ19632884756 小时前
ssm基于Springboot+的球鞋销售商城网站vue
vue.js·spring boot·后端
太空眼睛7 小时前
【MCP】使用SpringBoot基于Streamable-HTTP构建MCP-Server
spring boot·sse·curl·mcp·mcp-server·spring-ai·streamable