SpringBoot项目里,如何让ShardingSphere 5.x和dynamic-datasource和平共处?一个配置类搞定混合数据源
SpringBoot项目中ShardingSphere 5.x与dynamic-datasource的混合数据源架构实践在电商系统这类高并发场景下订单表通常需要分库分表来应对海量数据而商品配置、用户签约等业务表则更适合单库存储。这种混合架构带来了技术挑战如何在同一个SpringBoot项目中同时使用ShardingSphere的分片能力和dynamic-datasource的多数据源路由1. 混合数据源架构的核心挑战当订单表需要水平分片而商品表需要独立存储时传统方案往往面临两难选择。ShardingSphere擅长分库分表但对非分片数据源支持有限dynamic-datasource精于多数据源路由却无法处理分片逻辑。典型痛点包括分片数据源无法参与多数据源路由事务跨越分片库和独立库时的一致性难题两种数据源框架的配置属性冲突监控指标难以统一收集关键突破点在于将ShardingSphere管理的分片数据源作为一个逻辑数据源注册到dynamic-datasource体系中。这种架构下应用层通过统一的DS注解即可透明访问各类数据源。2. 依赖配置与初始化陷阱正确的依赖版本组合是成功的第一步。以下是经生产验证的依赖配置!-- 数据源核心 -- dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-starter/artifactId version1.2.8/version /dependency !-- ShardingSphere -- dependency groupIdorg.apache.shardingsphere/groupId artifactIdshardingsphere-jdbc-core-spring-boot-starter/artifactId version5.3.2/version /dependency !-- 动态数据源 -- dependency groupIdcom.baomidou/groupId artifactIddynamic-datasource-spring-boot-starter/artifactId version3.6.1/version /dependency !-- MyBatis增强 -- dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency注意ShardingSphere 5.x版本必须配合dynamic-datasource 3.5使用低版本会导致自动配置冲突。YAML配置需要特别注意属性隔离。示例配置片段spring: shardingsphere: datasource: names: db0,db1 db0: url: jdbc:mysql://db-host:3306/db0 type: com.alibaba.druid.pool.DruidDataSource db1: url: jdbc:mysql://db-host:3306/db1 type: com.alibaba.druid.pool.DruidDataSource rules: sharding: tables: orders: actual-data-nodes: db0.orders_$-{0..2} datasource: dynamic: primary: master datasource: master: url: jdbc:mysql://db-host:3306/master config: url: jdbc:mysql://db-host:3306/config_db3. 核心配置类实现真正的魔法发生在自定义配置类中。以下是一个经过生产验证的增强版配置实现Configuration AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class}) public class HybridDataSourceConfig { Autowired private DynamicDataSourceProperties properties; Lazy // 必须延迟加载 Autowired(required false) private DataSource shardingSphereDataSource; Bean public DynamicDataSourceProvider dynamicDataSourceProvider() { return new AbstractDataSourceProvider() { Override public MapString, DataSource loadDataSources() { MapString, DataSource dataSourceMap createDataSourceMap( properties.getDatasource()); if (shardingSphereDataSource ! null) { dataSourceMap.put(sharding, shardingSphereDataSource); } return dataSourceMap; } }; } Primary Bean public DataSource dataSource(DynamicDataSourceProvider provider) { DynamicRoutingDataSource ds new DynamicRoutingDataSource(); ds.setPrimary(properties.getPrimary()); ds.setStrict(properties.getStrict()); ds.setProvider(provider); return enhanceDataSource(ds); } private DataSource enhanceDataSource(DataSource dataSource) { // 添加监控埋点等增强逻辑 return dataSource; } }关键实现要点AutoConfigureBefore确保在动态数据源自动配置前执行Lazy解决ShardingSphere数据源初始化时机问题空检查避免未启用ShardingSphere时报错增强方法预留监控扩展点4. 业务层使用规范在Mapper层通过DS注解指定数据源时推荐采用以下策略// 分片数据源访问 DS(sharding) public interface OrderMapper { Select(SELECT * FROM orders WHERE order_no #{orderNo}) Order findByOrderNo(Param(orderNo) String orderNo); } // 独立数据源访问 DS(config) public interface ProductConfigMapper { Update(UPDATE product SET price #{price} WHERE id #{id}) int updatePrice(Param(id) Long id, Param(price) BigDecimal price); } // 动态切换示例 public class OrderService { DS(sharding) public Order getOrder(String orderNo) { // 访问分片库 } DS(config) public void updateProductConfig(Product product) { // 访问独立配置库 } }对于需要跨数据源事务的场景建议使用Seata分布式事务或将本地事务拆分为最终一致性模式避免在同一个方法内混用不同DS注解5. 生产环境优化策略经过多个线上项目验证以下优化措施能显著提升稳定性连接池配置优化参数分片数据源建议值独立数据源建议值initialSize105maxActive5020minIdle105maxWait3000ms1000mstimeBetweenEviction60000ms30000ms监控集成方案public class DataSourceMonitor implements DataSourceCreator { Override public DataSource createDataSource(DataSourceProperty property) { DruidDataSource ds property.createDruidDataSource(); // 添加Prometheus监控 DruidStatManager.addDataSource(ds, property.getPollName()); return ds; } }常见故障排查指南连接泄漏启用druid的removeAbandoned配置分片不生效检查SQL是否包含分片键路由错误确认DS注解值是否与注册名称一致事务失效确保没有绕过Spring代理6. 架构演进建议当系统发展到一定规模后可以考虑将配置类数据迁移到配置中心使用ShardingSphere-Proxy替代嵌入式分片引入数据同步工具保证跨数据源数据一致性对高频访问的非分片数据实施缓存策略这套混合架构已在多个日订单百万级的电商系统中验证既能享受分库分表的扩展性又能保持简单业务的开发效率。关键在于合理划分数据边界避免过度设计。