dynamic-datasource数据源路由规则:数据库类型

dynamic-datasource数据源路由规则:数据库类型

【免费下载链接】dynamic-datasource dynamic datasource for springboot 多数据源 动态数据源 主从分离 读写分离 分布式事务 【免费下载链接】dynamic-datasource 项目地址: https://gitcode.com/gh_mirrors/dy/dynamic-datasource

在现代应用开发中,随着数据量的增长和业务复杂度的提升,单一数据源往往难以满足系统需求。dynamic-datasource作为一款优秀的多数据源解决方案,为Spring Boot应用提供了灵活高效的数据源管理能力。本文将深入探讨dynamic-datasource的数据源路由规则,帮助开发者更好地理解和应用这一强大工具。

核心路由组件

dynamic-datasource的数据源路由功能核心由DynamicRoutingDataSource类实现,该类继承自AbstractRoutingDataSource,并实现了InitializingBeanDisposableBean接口,负责数据源的初始化、路由和销毁等关键操作。

public class DynamicRoutingDataSource extends AbstractRoutingDataSource implements InitializingBean, DisposableBean {
    // 核心实现代码
}

dynamic-datasource-spring/src/main/java/com/baomidou/dynamic/datasource/DynamicRoutingDataSource.java

数据源存储结构

DynamicRoutingDataSource使用两个重要的Map结构来存储数据源信息:

  1. dataSourceMap: 存储所有已配置的数据源,key为数据源名称,value为数据源实例。
  2. groupDataSources: 存储分组数据源,key为分组名称,value为GroupDataSource实例。

这两个Map的定义如下:

/**
 * 所有数据库
 */
private final Map<String, DataSource> dataSourceMap = new ConcurrentHashMap<>();
/**
 * 分组数据库
 */
private final Map<String, GroupDataSource> groupDataSources = new ConcurrentHashMap<>();

路由策略接口

dynamic-datasource定义了DynamicDataSourceStrategy接口,作为所有数据源路由策略的基础。该接口只有一个determineKey方法,用于从数据源列表中选择一个数据源。

public interface DynamicDataSourceStrategy {
    /**
     * determine a database from the given dataSources
     *
     * @param dsNames given dataSources
     * @return final dataSource
     */
    String determineKey(List<String> dsNames);
}

dynamic-datasource-spring/src/main/java/com/baomidou/dynamic/datasource/strategy/DynamicDataSourceStrategy.java

内置路由策略

dynamic-datasource提供了两种内置的路由策略:负载均衡策略和随机策略。

负载均衡策略

LoadBalanceDynamicDataSourceStrategy实现了基于轮询的负载均衡策略。它使用一个原子整数作为计数器,每次请求时自增并取模,从而实现数据源的轮询选择。

public class LoadBalanceDynamicDataSourceStrategy implements DynamicDataSourceStrategy {
    /**
     * 负载均衡计数器
     */
    private final AtomicInteger index = new AtomicInteger(0);

    @Override
    public String determineKey(List<String> dsNames) {
        return dsNames.get(Math.abs(index.getAndAdd(1) % dsNames.size()));
    }
}

dynamic-datasource-spring/src/main/java/com/baomidou/dynamic/datasource/strategy/LoadBalanceDynamicDataSourceStrategy.java

随机策略

RandomDynamicDataSourceStrategy实现了随机选择数据源的策略。它使用ThreadLocalRandom来生成随机数,从而在数据源列表中随机选择一个数据源。

public class RandomDynamicDataSourceStrategy implements DynamicDataSourceStrategy {
    @Override
    public String determineKey(List<String> dsNames) {
        return dsNames.get(ThreadLocalRandom.current().nextInt(dsNames.size()));
    }
}

dynamic-datasource-spring/src/main/java/com/baomidou/dynamic/datasource/strategy/RandomDynamicDataSourceStrategy.java

数据源路由流程

dynamic-datasource的数据源路由流程主要包括以下几个关键步骤:

1. 获取数据源标识

determineDataSource方法是路由的入口点,它通过DynamicDataSourceContextHolder.peek()获取当前线程的数据源标识(dsKey)。

@Override
public DataSource determineDataSource() {
    String dsKey = DynamicDataSourceContextHolder.peek();
    return getDataSource(dsKey);
}

2. 数据源选择逻辑

getDataSource方法实现了核心的数据源选择逻辑:

  1. 如果dsKey为空,则使用主数据源(primary)。
  2. 如果dsKey对应一个分组数据源,则使用该分组的路由策略选择具体数据源。
  3. 如果dsKey对应一个具体数据源,则直接使用该数据源。
  4. 如果strict模式为true且未找到对应数据源,则抛出异常;否则使用主数据源。
public DataSource getDataSource(String ds) {
    if (DsStrUtils.isEmpty(ds)) {
        return determinePrimaryDataSource();
    } else if (!groupDataSources.isEmpty() && groupDataSources.containsKey(ds)) {
        log.debug("dynamic-datasource switch to the datasource named [{}]", ds);
        return groupDataSources.get(ds).determineDataSource();
    } else if (dataSourceMap.containsKey(ds)) {
        log.debug("dynamic-datasource switch to the datasource named [{}]", ds);
        return dataSourceMap.get(ds);
    }
    if (strict) {
        throw new CannotFindDataSourceException("dynamic-datasource could not find a datasource named " + ds);
    }
    return determinePrimaryDataSource();
}

3. 主数据源选择

determinePrimaryDataSource方法用于选择主数据源,优先检查主数据源名称是否对应一个分组,若否,则直接使用主数据源名称对应的具体数据源。

private DataSource determinePrimaryDataSource() {
    log.debug("dynamic-datasource switch to the primary datasource");
    DataSource dataSource = dataSourceMap.get(primary);
    if (dataSource != null) {
        return dataSource;
    }
    GroupDataSource groupDataSource = groupDataSources.get(primary);
    if (groupDataSource != null) {
        return groupDataSource.determineDataSource();
    }
    throw new CannotFindDataSourceException("dynamic-datasource can not find primary datasource");
}

分组数据源

dynamic-datasource支持将多个数据源划分为一个组,通过分组名称可以路由到该组中的某个数据源。分组的实现主要通过以下机制:

数据源名称约定

数据源名称采用"分组名_数据源名"的格式,例如"master_0"、"master_1"、"slave_0"等。系统通过下划线分割来识别分组。

分组数据源创建

在添加数据源时,系统会自动检查数据源名称是否包含下划线,如果包含,则将其添加到对应的分组中:

private void addGroupDataSource(String ds, DataSource dataSource) {
    if (ds.contains(UNDERLINE)) {
        String group = ds.split(UNDERLINE)[0];
        GroupDataSource groupDataSource = groupDataSources.get(group);
        if (groupDataSource == null) {
            try {
                groupDataSource = new GroupDataSource(group, strategy.getDeclaredConstructor().newInstance());
                groupDataSources.put(group, groupDataSource);
            } catch (Exception e) {
                throw new RuntimeException("dynamic-datasource - add the datasource named " + ds + " error", e);
            }
        }
        groupDataSource.addDatasource(ds, dataSource);
    }
}

路由策略配置

dynamic-datasource允许通过配置文件自定义路由策略。默认情况下,系统使用LoadBalanceDynamicDataSourceStrategy作为路由策略。

@Setter
private Class<? extends DynamicDataSourceStrategy> strategy = LoadBalanceDynamicDataSourceStrategy.class;

开发者可以通过以下方式修改默认的路由策略:

spring:
  datasource:
    dynamic:
      strategy: com.baomidou.dynamic.datasource.strategy.RandomDynamicDataSourceStrategy

路由流程总结

为了更直观地理解dynamic-datasource的数据源路由流程,我们可以用以下流程图表示:

mermaid

总结

dynamic-datasource通过灵活的数据源路由规则,为Spring Boot应用提供了强大的多数据源管理能力。本文详细介绍了dynamic-datasource的核心路由组件、路由策略接口、内置路由策略、数据源路由流程以及分组数据源的实现机制。

通过合理配置和使用这些路由规则,开发者可以轻松实现主从分离、读写分离等高级数据源管理功能,满足不同业务场景的需求。

希望本文能够帮助开发者更好地理解和应用dynamic-datasource的数据源路由功能,为构建高性能、高可用的应用系统提供有力支持。

如果您对dynamic-datasource的使用还有其他疑问,欢迎查阅官方文档或参与社区讨论。

官方文档

【免费下载链接】dynamic-datasource dynamic datasource for springboot 多数据源 动态数据源 主从分离 读写分离 分布式事务 【免费下载链接】dynamic-datasource 项目地址: https://gitcode.com/gh_mirrors/dy/dynamic-datasource

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值