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 小时前
黄金、碳排放期货市场API接口文档
java·开发语言·spring boot·后端·金融·区块链
胡斌附体1 小时前
微服务中 本地启动 springboot 无法找到nacos配置 启动报错
java·spring boot·微服务·yml·naocs yml
向哆哆3 小时前
Spring Boot快速开发:从零开始搭建一个企业级应用
java·spring boot·后端
eternal__day9 小时前
Spring Boot 实现验证码生成与校验:从零开始构建安全登录系统
java·spring boot·后端·安全·java-ee·学习方法
宛如昨晚没早睡12 小时前
SpringBoot的自动配置和起步依赖原理
spring boot
源码云商12 小时前
Spring Boot + Vue 实现在线视频教育平台
vue.js·spring boot·后端
Micro麦可乐15 小时前
最新Spring Security实战教程(十四)OAuth2.0精讲 - 四种授权模式与资源服务器搭建
java·服务器·spring boot·spring·spring security·oauth2·oauth2授权
caihuayuan516 小时前
[数据库之十四] 数据库索引之位图索引
java·大数据·spring boot·后端·课程设计
天上掉下来个程小白17 小时前
缓存菜品-04.功能测试
java·spring boot·缓存·微信小程序·需求分析·苍穹外卖