使用sharding-jdbc解决SaaS系统动态数据源问题

本文介绍了如何在SaaS系统中解决动态数据源问题,探讨了共享数据表、独立schema和独立数据库三种数据隔离方案,并详细阐述了采用独立数据库并利用sharding-jdbc进行分库的实现思路。通过创建租户时指定数据源,结合AOP拦截器实现数据源切换,确保每个租户的数据安全性。
摘要由CSDN通过智能技术生成

1. 需求背景

项目是toB系统,技术设计的时候需要考虑系统SaaS化,也就是实现多租户模式;

2. 设计思路

个人之前并未参与过SaaS系统的设计和开发,也参考了网上的大量资料学习,SaaS系统的核心个人感觉主要有三点:

  1. 动态数据源问题;
  2. 权限控制问题;
  3. 个性化需求问题;

由于第3点这里并不展开讨论;但对于toB系统比较成熟,所以一般做的时候应该也都满足绝大多数企业的要求;

2.1 SaaS数据隔离的三种方案

2.1.1 共享数据表(tenant_id)

所有的租户共用同一套数据库和表结构,不同租户之间的数据通过tenant_id进行区分,可见所有表结构中都需要添加此字段,在项目查询的时候,tenant_id也是必传的一个字段。

项目实现中最好是将tenant_id通过ThreadLocal进行传递,mybatis层面通过自定义sql拦截器,修改sql语句添加 tenant_id的where条件;

2.1.2 独立schema

每个租户数据是放在同一台数据库系统,但是通过不同的数据库实例进行区分,此种方式就需要项目去实现动态数据源,不同的租户访问各自的数据库实例;

2.1.3 独立数据库

独立数据库此方式数据安全性方面更高,但成本会有点大,每个租户都需要有独立的数据库服务,但也需要考虑这种场景,有A企业虽然想使用此SaaS项目,但是A公司希望是将数据存储在A公司服务器中,这种方式就只能使用独立数据库;

2.2 创建租户思路

2.2.1 创建租户时指定数据源

项目角色主要包括:超级管理员、租户管理员、普通用户;

  • 超级管理员:超级管理员管理着所有的租户信息;
  • 租户管理员:只能管理当前租户下的数据;
  • 普通用户:某租户下的普通用户(业务人员);
    在这里插入图片描述
    数据源隔离我们采用的是后两种,每个租户都有自己的数据库实例,但也可以指定数据库服务的url;
    主要参考以下建议:
  1. 项目牵扯到的数据安全性要求相对较高;
  2. 数据库采用的是RDS,可以根据每个服务的要求创建出不同的数据库硬件配置;
  3. 能满足企业将数据保存到自己服务器的要求;
2.2.2 创建租户流程

在这里插入图片描述
流程有所简化,比如一些计费等功能,但大体上我们创建一个租户之后,一方面把租户的信息维护到当前超级管理员所在的数据表中,然后切换到新创建的租户数据源中执行初始化相关的SQL(这块SQL是维护到配置系统中的,直接读取之后,执行创建相关表结构)。SQL初始化完成之后,创建租户的管理员账号,大体流程就结束了;

最后一步将租户和数据库信息保存到redis中是因为,一般项目是集群部署,虽然这次在A机器上执行了动态创建数据源,但是在B机器上可能还未初始化,所以在每次使用数据源之前都会先进行判断,是否已经动态创建,如未创建,则创建之后再使用租户的数据源;

3. 代码实现思路

代码实现方面我是通过sharding-jdbc提供的分库功能实现的;代码分为3部分:

  1. sharding-jdbc自定义分库策略
  2. 创建租户
  3. 动态初始化数据源

3.1 项目前期准备

3.1.1 maven配置
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-core</artifactId>
    <version>4.0.0-RC1</version>
</dependency>
3.1.2 yml配置
spring:
  datasource:
    name: admin
    hikari:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://127.0.0.1:3306/saas_demo?characterEncoding=utf-8&serverTimezone=GMT
      username: xxx
      password: xxx
3.1.3 其它配置

springboot启动类中将DataSourceAutoConfiguration排除掉,因为我们需要自己定义创建;

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class ShardingTestApplication {
   

    public static void main(String[] args) {
   
        SpringApplication.run(ShardingTestApplication.class, args);
    }

}

3.2 初始化默认数据源

由于上面我们把DataSourceAutoConfiguration的创建排除掉了,所以我们需要自己创建一个默认数据源交给sharding-jdbc;

@Configuration
public class DataSourceConfig {
   

    private static int dataSourceSize = 8;
    // admin数据源名称
    @Value("${spring.datasource.name}")
    private 
评论 78
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值