利用Spring Cloud开发微服务并实现动态数据源路由详解

本文介绍了在微服务架构中实现动态数据源路由的方法,特别是针对多租户SAAS系统的解决方案。通过创建一个名为dynamicDS-spring-boot-starter的Spring Boot Starter,实现了动态配置数据源。详细讲解了配置、核心类的功能,包括DynamicDatasourceConfigProperties、DynamicDSAutoConfiguration、EnableDynamicDS等,并展示了如何在微服务中使用这个Starter来支持动态数据源,以及如何配置application.yml文件。最后提供了一个简单的微服务示例,演示了如何通过HTTP请求头中的orgCode切换不同租户的数据源。
摘要由CSDN通过智能技术生成

  一个典型的微服务架构中,服务应该是没有状态的,但是对于一个多租户的SAAS类系统来说,每个租户都有自己的配置和业务数据,并且不同租户的之间的数据应该要满足一定程度的隔离性。

隔离方案一般有以下三种:

  描述 优点 缺点
独立数据库 一个租户一个数据库 隔离级别最高,安全性最好 成本较高
共享数据库,隔离数据架构 多个或所有租户共享Database,但是每个租户一个Schema 为安全性要求较高的租户提供了一定程度的逻辑数据隔离,并不是完全隔离;每个数据库可支持更多的租户数量 现故障,数据恢复比较困难,因为恢复数据库将牵涉到其他租户的数据
共享数据库,共享数据架构 租户共享同一个Database、同一个Schema,但在表中增加TenantID多租户的数据字段 成本最低,允许每个数据库支持的租户数量最多 隔离级别最低,安全性最低,需要在设计开发时加大对安全的开发量;
数据备份和恢复最困难,需要逐表逐条备份和还原

处于安全性和经济性的综合考虑,第二种“共享数据库,隔离数据架构”是大多数SAAS类系统采用的方案。


由于服务是没有状态的且各租户共享的,即一个服务实例可以处理来自不同租户中的用户发起的请求,那么服务必须要支持动态数据源,即当不同租户的用户访问服务时,服务可以动态路由到访问这个租户对应的数据源。

为了模拟这种应用场景,我在2个mysql数据库服务器上建立了几个租户数据库,如图所示:

其中jg6(代表机构6)在192.168.2.135上,jg3、jg4、jg5在192.168.2.143上,每个数据库里都有一个叫userinfo的表,

jg6上数据为:

jg3上的数据为:

jg4上的数据为:

jg5上的数据为:


接下来就是重点了,如何在Spring Cloud体系中优雅的实现动态数据源,思路如下:


  1.  开发一个支持动态配置的Spring Boot Starter 来支持动态数据源,我把它命名为 dynamicDS-spring-boot-starter,
    这个starter中包含一个@EnableDynamicDS注解。
  2. 需要动态数据源支持的微服务需要在pom.xml添加dynamicDS-spring-boot-starter依赖,并在应用启动类上添加
    @EnableDynamicDS注解。


dynamicDS-spring-boot-starter的组成,如图所示:

  • Application.java,自动生成的类,没啥意义,仅仅为了支持mvn clean install 编译而已,不然会不成功,提示没有Main Class.
  • DynamicDatasourceConfigProperties,这个类是为了接受微服务中动态数据源的配置(application.yml),具体怎么定义一个类接受application.yml的配置,请查阅相关文档,简单讲就是定义Map<String, String>和嵌套的Map--Map<String, Map<String,String>>,就能解决绝大多数问题了。
    package com.tay.dynamicds;
    
    import java.util.Map;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    import lombok.Data;
    
    @ConfigurationProperties(prefix = "dynamicds")
    @Data
    public class DynamicDatasourceConfigProperties {
    	private String orgCodeHeader;
    	private Map<String, String> general;
    	private Map<String, Map<String, String>> tenants;
    }
    
    微服务中application.yml中对应的动态数据源配置部分为:
    dynamicds:
      orgCodeHeader: orgCode  
      general:
        maxPoolSize: 10
        minIdle: 3
        defaultTenant : jg3
      tenants:
        jg3:
          url: jdbc:mysql://192.168.2.143:3306/jg3
          userName: root
          password: password
        jg4:
          url: jdbc:mysql://192.168.2.143:3306/jg4
          userName: root
          password: password
        jg5:
          url: jdbc:mysql://192.168.2.143:3306/jg5
          userName: root
          password: password
          maxPoolSize: 20
          minIdle: 6
        jg6:
          url: jdbc:mysql://192.168.2.135:3306/jg6
          userName: root
          password: password   
    你仔细对照阅读配置读取类和配置,就会明白他们之间的对应关系。
  • DynamicDSAutoConfiguration.java,动态数据源自动配置类,在里面定义了一些必要的Bean。
    package com.tay.dynamicds;
    
    import javax.sql.DataSource;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.context.properties
  • 11
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值