Closed ykgarfield closed 9 months ago
Please fill it out carefully, or it will be closed. 请认真填写,不然会直接关闭。
JDK Version(required): 17
SpringBoot Version(required): 2.5.12
dynamic-datasource-spring-boot-starter Version(required): 4.2.0
druid Version(optional):
使用 shardingsphere 5.3.2 ,结合 dynamic-datasource,做主库和分库, shardingsphere 使用了如下的形式配置数据源:
url: jdbc:shardingsphere:classpath:shardingsphere.yaml driverClassName: org.apache.shardingsphere.driver.ShardingSphereDriver
shardingsphere.yaml 配置大概如下:
shardingsphere.yaml
dataSources: # 4 个分库 test_0: dataSourceClassName: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver jdbcUrl: xxx test_1: dataSourceClassName: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver jdbcUrl: xxx test_2: dataSourceClassName: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver jdbcUrl: xxx test_3: dataSourceClassName: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver jdbcUrl: xxx
dynamic-datasource 的配置如下:
spring: datasource: dynamic: primary: main # 通过此属性指定主属性源名称 datasource: # 主数据源配置, 不需要进行分库分表 main: url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&zeroDateTimeBehavior=convertToNull&autoReconnect=true&serverTimezone=Asia/Shanghai username: xxx password: xxx driverClassName: com.mysql.jdbc.Driver # 分库分表数据源配置 sharding: url: jdbc:shardingsphere:classpath:shardingsphere.yaml driverClassName: org.apache.shardingsphere.driver.ShardingSphereDriver druid: validationQuery: select 1
项目启动之后,只是简单的初始化了 sharding 这个数据源,并不会去实际初始化 test_0 ~ test_3 这几个数据源。只有在第一次访问分库的时候才会去初始化这几个数据源,这就导致了第一次访问某个接口会比较慢(需要初始化多个数据源)。
Expected Result: 项目启动之后可以去初始化分库的数据源。
大概的思路如下,当前在项目中对 dynamic-datasource 的代码做了一些扩展:
ShardingDruidDataSourceCreator 继承 DruidDataSourceCreator, 在 createDataSource 方法中调用一次 getConnection() 方法,这样可以去初始化分库的数据源。
ShardingDruidDataSourceCreator
DruidDataSourceCreator
createDataSource
@Slf4j public class ShardingDruidDataSourceCreator extends DruidDataSourceCreator { public ShardingDruidDataSourceCreator() { } public ShardingDruidDataSourceCreator(DruidConfig gConfig, DruidFilterCallBack druidFilterCallBack) { super(gConfig, druidFilterCallBack); } @Override public DataSource createDataSource(DataSourceProperty dataSourceProperty) { DataSource dataSource = super.createDataSource(dataSourceProperty); try { // 获取连接进行初始化 Connection connection = dataSource.getConnection(); connection.close(); log.info("初始化分库分表数据源成功!"); } catch (SQLException e) { throw new RuntimeException("数据源连接失败,请检查配置!", e); } return dataSource; } @Override public boolean support(DataSourceProperty dataSourceProperty) { String jdbcUrl = dataSourceProperty.getUrl(); // jdbc url 以 jdbc:shardingsphere 开头 return StringUtils.startsWith(jdbcUrl, "jdbc:shardingsphere"); } }
ShardingDataSourceCreatorConfig 会创建上面的 ShardingDruidDataSourceCreator bean.
ShardingDataSourceCreatorConfig
@AutoConfigureBefore(value = DynamicDataSourceAutoConfiguration.class, name = "com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration") @Configuration @Component public class ShardingDataSourceCreatorConfig { // 在 DruidDataSourceCreator 之前初始化,这样在创建数据源的时候会优先执行 ShardingDruidDataSourceCreator public static final int SHARDING_SPHERE_ORDER = DynamicDataSourceCreatorAutoConfiguration.DRUID_ORDER - 1; @ConditionalOnClass(DruidDataSource.class) @Configuration @Slf4j static class DruidDataSourceCreatorConfiguration { @Autowired(required = false) private ApplicationContext applicationContext; @Bean @Order(SHARDING_SPHERE_ORDER) public ShardingDruidDataSourceCreator shardingDruidDataSourceCreator(DynamicDataSourceProperties properties) { DruidConfig druid = properties.getDruid(); return new ShardingDruidDataSourceCreator(druid, proxyFilters -> { List<Filter> filters = new ArrayList<>(); if (applicationContext != null && DsStrUtils.hasText(proxyFilters)) { for (String filterId : proxyFilters.split(",")) { try { filters.add(applicationContext.getBean(filterId, Filter.class)); } catch (Exception e) { log.warn("dynamic-datasource cannot load druid filter with name [{}], will be ignored", filterId); } } } return filters; }); } } }
不知道 dynamic-datasource 官方是否可以适配支持此特性。
Step 1
Step 2
Step 3
可以用event去做,查看一下源码包下的event
Please fill it out carefully, or it will be closed. 请认真填写,不然会直接关闭。
Enviroment
JDK Version(required): 17
SpringBoot Version(required): 2.5.12
dynamic-datasource-spring-boot-starter Version(required): 4.2.0
druid Version(optional):
Describe what happened
使用 shardingsphere 5.3.2 ,结合 dynamic-datasource,做主库和分库, shardingsphere 使用了如下的形式配置数据源:
shardingsphere.yaml
配置大概如下:dynamic-datasource 的配置如下:
项目启动之后,只是简单的初始化了 sharding 这个数据源,并不会去实际初始化 test_0 ~ test_3 这几个数据源。只有在第一次访问分库的时候才会去初始化这几个数据源,这就导致了第一次访问某个接口会比较慢(需要初始化多个数据源)。
Expected Result: 项目启动之后可以去初始化分库的数据源。
大概的思路如下,当前在项目中对 dynamic-datasource 的代码做了一些扩展:
ShardingDruidDataSourceCreator
继承DruidDataSourceCreator
, 在createDataSource
方法中调用一次 getConnection() 方法,这样可以去初始化分库的数据源。ShardingDataSourceCreatorConfig
会创建上面的ShardingDruidDataSourceCreator
bean.不知道 dynamic-datasource 官方是否可以适配支持此特性。
Steps to reproduce
Step 1
Step 2
Step 3