mysql 多租户_动态路由数据源(多租户)解决方案

当下有很多服务都使用了多数据源,或是出于跨库查询或是分库分表、读写分离等,多数据源解决方案早已不是稀罕事。常见的解决方案包括使用多数据源框架(例如Shareding-Jdbc)、在数据库端做代理(例如MYCAT)、对于固定的几个数据源连接,也可以直接手动配置多个数据源,这种相关处理有很多源码,我在github上也有简单的实现:fishstormX/dynamicDataSource: 动态数据源的实现,基于maven自定义多模块骨架。Spring Boot2.0.x,本文实现的是动态数据源,主要为了解决 多租户问题(不同的用户群组有不同的数据源和配置,强调数据的隔离性)。

实现和需求确认

本文技术能实现的是动态数据源,基于Spring框架,即能够将注入的Datasource根据租户不同使用不同的来源,同时根据租户增减动态的增删和缓存数据源(增是因为会有新增租户可能使用到项目启动后的数据源,减是因为租户数不可预料,不可直接缓存所有的数据源)。多个租户使用不同的数据源,但其Mapper(DAO层,本文基于Mybatis作为ORM框架,使用其他ORM亦可,多数据源配置与此无关)。涉及到的相关内容:

ORM框架确认(不限制,本文Mybatis);

多租户的性质和大致使用场景确认(假设单台数据源连接足够支撑,文后会讨论分布式方案);

Datasource相关参数调优和连接池类型选择(大致没有出入,本文使用Druid连接池)

Datasource缓存方式和过期清除(本文使用Guava的Cache进行数据的缓存)及新增

Datasource数据拉取和上下文数据信息存储

实现方案和流程设计

从本人角度看,比较多见的多租户很少有始终在使用的,所以数据库连接资源的释放是不可避免的,这样一来数据库资源的懒加载也很有必要,对于一些参数,通常要经过反复的才能达到最优,所以先选了一个比较中肯的过期时间——20分钟。所以本文也使用了Guava Cache进行数据源的缓存,确保不活跃的连接不再占用内存以及保证数据源连接的复用,一个关键点是我们不能让DataSource未过期前就抛弃掉(使用类似lru的方式),这种情况只能说明我们的服务承载能力不足。

数据的读取是通过外部的配置文件,也可以通过基于API的动态查询、基于动态配置中心等方式,此部分的实现本文不详述,能确保读到新增的配置即可,当然也可以从主数据源中读取。

动态数据源的核心是AbstractRoutingDataSource,在给定实现的基础上,他可以实现动态的路由指定数据源,同时配合ThreadLocal生成标识当前数据源的Context,这样就能避免过多的手动切换数据源。

本文代码在原始基础上做了改动,不适用于所有架构,一般可能需要做些参数和细节逻辑的调整。整体流程大致如下:

mysql 多租户_动态路由数据源(多租户)解决方案_第1张图片

代码实现

引入依赖

需要引入数据库连接的相关依赖(包括本文使用的Druid连接池)和Guava,一般项目中会有,如没有请自行引入。

定义数据源上下文

我们必须定义一个Context,让我们自己定义的DataSource能根据当前的Context选择数据源,将多租户的数据源使用唯一标识存储起来(譬如使用的用户id,保证不会冲突),且要定义主数据源的标识:

public class {

//存储上下文数据源

private static final ThreadLocal dataSourceKeyMapper = new ThreadLocal<>();

//设置当前线程的数据源标识,如果为空,使用主数据源。也就是通过此方法设置数据源

//我们在这里定义为master,也可直接置为空默认使用主数据源

public static void setDataSourceKey(String uid) {

if(null==uid){

contextMapper

你可能感兴趣的:(mysql,多租户)