读写分离V1:使用AbstractRoutingDataSource

读写分离V1:使用AbstractRoutingDataSource

一、AbstractRoutingDataSource 介绍

根据定义的规则选择对应的数据源

完整的代码:myreadwritesep-abstract-rounting-v1

二、pom依赖

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<exclusions>
				<exclusion>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-log4j2</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>${mybatis-spring-boot-starter.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>${druid-spring-boot-starter.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>${commons-lang3.version}</version>
		</dependency>
		
<think>我们正在讨论微服务项目中配置多数据源的几种方式。根据提供的引用和常见实践,我们可以总结以下几种主要方式: 1. **手动配置多数据源** 通过在Spring Boot应用中排除`DataSourceAutoConfiguration`,然后手动创建多个`DataSource` Bean,并为每个数据源配置独立的`JdbcTemplate`、`TransactionManager`等。这种方式灵活但代码量较大,需要自行管理事务和连接。 2. **使用第三方库(如Dynamic Datasource)** 引用[5]提到使用`dynamic-datasource-spring-boot-starter`库,这是MyBatis-Plus团队提供的多数据源解决方案。通过简单的配置即可实现多数据源,支持主从、读写分离等场景,并内置了事务管理。这是目前较为流行的轻量级方案。 3. **抽象为通用SDK** 引用[3]提到针对平台级微服务项目,可以将多数据源适配逻辑封装为SDK,各微服务通过引入SDK并少量配置即可实现多数据源。这种方式适合大型项目,能统一技术栈并减少重复工作。 4. **使用Spring Cloud的AbstractRoutingDataSource** 基于Spring的`AbstractRoutingDataSource`实现动态数据源路由。通过线程上下文(如ThreadLocal)决定当前操作使用的数据源,需自行实现数据源切换逻辑。 5. **分模块配置(适合Spring Cloud)** 引用[1][2]提到在微服务中为不同模块(如MySQL模块、DM模块)分别配置数据源。通常结合JPA或MyBatis的包扫描路径隔离不同数据源的DAO层。 --- ### 详细说明 #### 1. 手动配置多数据源(排除自动配置) **步骤**: 1. 主类排除自动配置: ```java @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) ``` 2. 配置多个数据源(以两个为例): ```java @Configuration public class DataSourceConfig { @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } } ``` 3. 为每个数据源配置独立的`JdbcTemplate`和`TransactionManager`。 **适用场景**:简单场景或需要高度定制化时。 #### 2. 使用Dynamic Datasource(推荐) **步骤**: 1. 添加依赖: ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.5.2</version> </dependency> ``` 2. 配置文件指定数据源: ```yaml spring: datasource: dynamic: primary: master # 默认数据源 datasource: master: # 主库 url: jdbc:mysql://localhost:3306/db1 username: root password: 123456 slave: # 从库 url: jdbc:mysql://localhost:3306/db2 username: root password: 123456 ``` 3. 使用`@DS`注解切换数据源: ```java @Service @DS("slave") // 指定从库 public class UserServiceImpl implements UserService { @Override public User getUser(Long id) { // 操作slave数据源 } } ``` **优点**:开箱即用,支持事务嵌套。 #### 3. 封装为SDK(平台级项目) **设计思路**: - 创建独立项目封装`AbstractRoutingDataSource`实现。 - 提供统一注解(如`@DataSource("name")`)和配置解析。 - 各微服务引入SDK后,通过配置文件激活多数据源。 **适用场景**:企业级多微服务项目统一技术栈。 #### 4. 基于AbstractRoutingDataSource动态路由 **核心代码**: ```java public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSourceType(); // 从ThreadLocal获取数据源key } } ``` **注意事项**:需配合AOP或拦截器实现数据源切换。 --- ### 对比总结 | 方式 | 复杂度 | 维护性 | 适用场景 | |--------------------------|--------|--------|------------------------------| | 手动配置 | 高 | 低 | 简单需求 | | Dynamic Datasource | 低 | 高 | 多数微服务项目(推荐) | | 封装SDK | 中 | 高 | 平台级多微服务架构 | | AbstractRoutingDataSource| 中 | 中 | 需深度定制路由策略 | > 提示:选择方案时需考虑事务一致性需求。跨数据源事务需引入JTA(如Atomikos)[^4]。 --- §§相关问题§§ 1. Dynamic Datasource如何实现读写分离? 2. 微服务中如何处理跨数据源的事务? 3. 使用多数据源后如何监控不同数据库的连接池状态? 4. 如何用Flyway管理多数据源的数据库版本?[^5] </think>### 微服务项目配置多数据源的常见方式 #### 1. **手动配置多数据源(基础方案)** **核心步骤**: 1. 排除自动数据源配置 ```java @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) ``` 2. 手动创建多个数据源 Bean ```java @Configuration public class DataSourceConfig { @Bean @ConfigurationProperties("spring.datasource.master") public DataSource masterDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties("spring.datasource.slave") public DataSource slaveDataSource() { return DataSourceBuilder.create().build(); } } ``` 3. 配置文件定义连接参数 ```yaml spring: datasource: master: url: jdbc:mysql://master:3306/db username: root password: root slave: url: jdbc:mysql://slave:3306/db username: readonly password: readonly ``` **适用场景**:简单业务场景,数据源数量固定[^4] #### 2. **Dynamic-Datasource 动态路由(主流方案)** **实现原理**:基于 Spring AOP 实现运行时数据源切换 **步骤**: 1. 添加依赖 ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> </dependency> ``` 2. 配置文件声明数据源 ```yaml spring: datasource: dynamic: primary: master datasource: master: url: jdbc:mysql://master:3306/db slave1: url: jdbc:mysql://slave1:3306/db slave2: url: jdbc:mysql://slave2:3306/db ``` 3. 使用注解切换数据源 ```java @Service @DS("slave1") // 指定数据源 public class OrderService { // 所有查询操作使用slave1数据源 } ``` **优势**: - 支持读写分离、分库分表 - 内置故障转移机制 - 无缝集成 MyBatis-Plus[^5] #### 3. **SDK 抽象封装(平台级方案)** **实施流程**: ```mermaid graph LR A[开发通用SDK] --> B[封装数据源路由] A --> C[集成事务管理] A --> D[提供配置接口] E[微服务项目] --> F[引入SDK依赖] E --> G[配置数据源参数] E --> H[使用注解切换] ``` **核心价值**: - 统一技术栈,降低各微服务适配成本 - 支持动态扩容数据源 - 集中监控和管理连接池[^3] #### 4. **云原生方案(Service Mesh)** **架构特点**: ```mermaid graph BT A[微服务] --> B(Service Mesh Sidecar) B --> C[(数据源1)] B --> D[(数据源2)] B --> E[(数据源N)] ``` **实现方式**: 1. 通过 Istio/Linkerd 配置流量规则 2. 使用 Database Mesh 组件(如 ShardingSphere-Proxy) 3. 声明式路由策略: ```yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService spec: hosts: ["mysql-service"] http: - route: - destination: host: mysql-read-pool # 读请求路由 ``` **适用场景**:超大规模微服务集群[^1] --- ### 方案对比矩阵 | 方案 | 复杂度 | 动态扩容 | 事务管理 | 适用规模 | |-----------------------|--------|----------|----------------|----------------| | 手动配置 | ★★☆ | ✘ | 需自行实现 | 小型项目 | | Dynamic-Datasource | ★★☆ | ✔ | 内置支持 | 中大型项目 | | SDK封装 | ★★★ | ✔ | 可定制化 | 平台级项目 | | Service Mesh | ★★★★ | ✔ | 基础设施层解决 | 超大规模集群 | > **最佳实践建议**: > - 常规项目首选 `Dynamic-Datasource`(引用[5]方案) > - 平台型产品采用 SDK 抽象方案(引用[3]方案) > - 需注意跨数据源事务需引入 JTA/XA 协议[^2] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值