赞
踩
注意mysql为master
- datasource:
- mysql:
- master:
- type: com.alibaba.druid.pool.DruidDataSource
- driver-class-name: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://192.168.110.1222:3306/sdkjoy-db?characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
- username: root
- password:
- starrocks:
- type: com.alibaba.druid.pool.DruidDataSource
- driver-class-name: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql:loadbalance://192.168.110.1111:9030,192.168.110.1222:9030,192.168.110.1333:9030?useUnicode=true&autoReconnect=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
- addr: 192.168.110.1111:9030,192.168.110.12222:9030,192.168.110.1333:9030
- http:
- head: http://
- port: 8030
- username:
- password:
因为mysql给定了定时任务,项目启动必须访问要以mysql为master
- package com.skyable.monitor.config.datasource;
-
- import com.alibaba.druid.pool.DruidDataSource;
- import com.skyable.monitor.mapper.mysql.ClusterMapper;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
-
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Objects;
-
- /**
- * Description:
- *
- * @author
- * @date: 2023-02-21-13:55
- */
- @Component
- public class StarrocksDatasource {
- @Autowired private DataSourceUtil dataSourceUtil;
- @Autowired private ClusterMapper clusterMapper;
- /**
- * 连接starRocks数据源
- *
- * @param clusterId
- * @return
- */
- public Boolean datasource(Integer clusterId) {
- HashMap<String, String> map = new HashMap(4);
- List<String> addr = clusterMapper.selectIp(clusterId);
- List<String> result = new ArrayList<>();
- for (String s : addr) {
- StringBuilder stringBuilder = new StringBuilder();
- StringBuilder append = stringBuilder.append(s).append(":").append("9030");
- result.add(append.toString());
- }
- String ip = String.join(",", result);
- map.put("type", "com.alibaba.druid.pool.DruidDataSource");
- map.put("driver-class-name", "com.mysql.cj.jdbc.Driver");
- map.put(
- "url",
- "jdbc:mysql:loadbalance://"
- + ip
- + "?useUnicode=true&autoReconnect=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai");
- map.put("addr", ip);
- map.put("username", "root");
- map.put("password", "");
- DataSourceInfo dataSourceInfo = new DataSourceInfo();
- dataSourceInfo.setUrl(map.get("url"));
- dataSourceInfo.setDatasourceKey(String.valueOf(clusterId));
- dataSourceInfo.setUserName(map.get("username"));
- dataSourceInfo.setPassword(map.get("password"));
- DruidDataSource druidDataSource = dataSourceUtil.createDataSourceConnection(dataSourceInfo);
- if (Objects.nonNull(druidDataSource)) {
- dataSourceUtil.addDefineDynamicDataSource(druidDataSource, dataSourceInfo.getDatasourceKey());
- DynamicDataSourceHolder.setDynamicDataSourceKey(String.valueOf(clusterId));
- }
- return true;
- }
- }
- package com.skyable.monitor.config.datasource;
-
- import org.springframework.beans.factory.InitializingBean;
- import org.springframework.jdbc.datasource.AbstractDataSource;
- import org.springframework.jdbc.datasource.lookup.DataSourceLookup;
- import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
- import org.springframework.lang.Nullable;
- import org.springframework.util.Assert;
- import org.springframework.util.CollectionUtils;
-
- import javax.sql.DataSource;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.util.Map;
-
- public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
- //目标数据源map集合,存储将要切换的多数据源bean信息
- @Nullable
- private Map<Object, Object> targetDataSources;
- //未指定数据源时的默认数据源对象
- @Nullable
- private Object defaultTargetDataSource;
- private boolean lenientFallback = true;
- //数据源查找接口,通过该接口的getDataSource(String dataSourceName)获取数据源信息
- private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
- //解析targetDataSources之后的DataSource的map集合
- @Nullable
- private Map<Object, DataSource> resolvedDataSources;
- @Nullable
- private DataSource resolvedDefaultDataSource;
-
- @Override
- //将targetDataSources的内容转化一下放到resolvedDataSources中,将defaultTargetDataSource转为DataSource赋值给resolvedDefaultDataSource
- public void afterPropertiesSet() {
- //如果目标数据源为空,会抛出异常,在系统配置时应至少传入一个数据源
- if (this.targetDataSources == null) {
- throw new IllegalArgumentException("Property 'targetDataSources' is required");
- } else {
- //初始化resolvedDataSources的大小
- this.resolvedDataSources = CollectionUtils.newHashMap(this.targetDataSources.size());
- //遍历目标数据源信息map集合,对其中的key,value进行解析
- this.targetDataSources.forEach((key, value) -> {
- //resolveSpecifiedLookupKey方法没有做任何处理,只是将key继续返回
- Object lookupKey = this.resolveSpecifiedLookupKey(key);
- //将目标数据源map集合中的value值(德鲁伊数据源信息)转为DataSource类型
- DataSource dataSource = this.resolveSpecifiedDataSource(value);
- //将解析之后的key,value放入resolvedDataSources集合中
- this.resolvedDataSources.put(lookupKey, dataSource);
- });
- if (this.defaultTargetDataSource != null) {
- //将默认目标数据源信息解析并赋值给resolvedDefaultDataSource
- this.resolvedDefaultDataSource = this.resolveSpecifiedDataSource(this.defaultTargetDataSource);
- }
-
- }
- }
-
- protected Object resolveSpecifiedLookupKey(Object lookupKey) {
- return lookupKey;
- }
-
- protected DataSource resolveSpecifiedDataSource(Object dataSource) throws IllegalArgumentException {
- if (dataSource instanceof DataSource) {
- return (DataSource)dataSource;
- } else if (dataSource instanceof String) {
- return this.dataSourceLookup.getDataSource((String)dataSource);
- } else {
- throw new IllegalArgumentException("Illegal data source value - only [javax.sql.DataSource] and String supported: " + dataSource);
- }
- }
- @Override
- //因为AbstractRoutingDataSource继承AbstractDataSource,而AbstractDataSource实现了DataSource接口,所有存在获取数据源连接的方法
- public Connection getConnection() throws SQLException {
- return this.determineTargetDataSource().getConnection();
- }
- @Override
- public Connection getConnection(String username, String password) throws SQLException {
- return this.determineTargetDataSource().getConnection(username, password);
- }
-
- protected DataSource determineTargetDataSource() {
- Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
- //调用实现类中重写的determineCurrentLookupKey方法拿到当前线程要使用的数据源的名称
- Object lookupKey = this.determineCurrentLookupKey();
- //去解析之后的数据源信息集合中查询该数据源是否存在,如果没有拿到则使用默认数据源resolvedDefaultDataSource
- DataSource dataSource = (DataSource)this.resolvedDataSources.get(lookupKey);
- if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
- dataSource = this.resolvedDefaultDataSource;
- }
-
- if (dataSource == null) {
- throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
- } else {
- return dataSource;
- }
- }
-
- @Nullable
- protected abstract Object determineCurrentLookupKey();
- }
- package com.skyable.monitor.config.datasource;
-
- /**
- * @Description: 动态数据源常量类
- *
- */
- public class CommonConstant {
- /**
- * 默认数据源标识
- */
- public static final String MASTER = "master";
- }
- package com.skyable.monitor.config.datasource;
-
- import lombok.Data;
-
- @Data
- public class DataSourceInfo {
- private String url;
- private String userName;
- private String password;
- private String datasourceKey;
- }
- package com.skyable.monitor.config.datasource;
-
- import com.alibaba.druid.pool.DruidDataSource;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Component;
-
- import javax.annotation.Resource;
- import java.sql.SQLException;
- import java.util.Map;
-
- /**
- * @Description: 数据源工具类
- * @Date 2022/8/18 17:20
- *
- */
- @Slf4j
- @Component
- public class DataSourceUtil {
-
- @Resource
- DynamicDataSource dynamicDataSource;
-
- /**
- * @Description: 根据传递的数据源信息测试数据库连接
- * @Author zhangyu
- */
- public DruidDataSource createDataSourceConnection(DataSourceInfo dataSourceInfo) {
- DruidDataSource druidDataSource = new DruidDataSource();
- druidDataSource.setUrl(dataSourceInfo.getUrl());
- druidDataSource.setUsername(dataSourceInfo.getUserName());
- druidDataSource.setPassword(dataSourceInfo.getPassword());
- druidDataSource.setBreakAfterAcquireFailure(true);
- druidDataSource.setConnectionErrorRetryAttempts(0);
- try {
- druidDataSource.getConnection(2000);
- log.info("数据源连接成功");
- return druidDataSource;
- } catch (SQLException throwables) {
- log.error("数据源 {} 连接失败,用户名:{},密码 {}",dataSourceInfo.getUrl(),dataSourceInfo.getUserName(),dataSourceInfo.getPassword());
- return null;
- }
- }
-
- /**
- * @Description: 将新增的数据源加入到备份数据源map中
- * @Author zhangyu
- */
- public void addDefineDynamicDataSource(DruidDataSource druidDataSource, String dataSourceName){
- Map<Object, Object> defineTargetDataSources = dynamicDataSource.getDefineTargetDataSources();
- defineTargetDataSources.put(dataSourceName, druidDataSource);
- dynamicDataSource.setTargetDataSources(defineTargetDataSources);
- dynamicDataSource.afterPropertiesSet();
- }
- }
- package com.skyable.monitor.config.datasource;
-
- import com.alibaba.druid.pool.DruidDataSource;
- import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Primary;
-
- import javax.sql.DataSource;
- import java.util.HashMap;
- import java.util.Map;
-
-
- @Configuration
- @MapperScan("com.skyable.monitor.mapper")
- public class DruidConfig {
-
- @Bean(name = CommonConstant.MASTER)
- @ConfigurationProperties("spring.datasource.mysql.master")
- public DruidDataSource masterDataSource()
- {
- DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
- return dataSource;
- }
-
- @Bean(name = "starrocksDataSource")
- @ConfigurationProperties("spring.datasource.starrocks")
- public DruidDataSource deafultStarRocksDataSource()
- {
- DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
- return dataSource;
- }
-
- @Bean
- @Primary
- public DynamicDataSource dynamicDataSource()
- {
- Map<Object, Object> dataSourceMap = new HashMap<>(2);
- dataSourceMap.put(CommonConstant.MASTER,masterDataSource());
- //设置动态数据源
- DynamicDataSource dynamicDataSource = new DynamicDataSource();
- dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
- dynamicDataSource.setTargetDataSources(dataSourceMap);
- //将数据源信息备份在defineTargetDataSources中
- dynamicDataSource.setDefineTargetDataSources(dataSourceMap);
- return dynamicDataSource;
- }
- }
- package com.skyable.monitor.config.datasource;
-
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
-
- import java.util.Map;
-
- /**
- * 动态数据源
- * 调用AddDefineDataSource组件的addDefineDynamicDataSource()方法,获取原来targetdatasources的map,并将新的数据源信息添加到map中,并替换targetdatasources中的map
- * 切换数据源时可以使用@DataSource(value = "数据源名称"),或者DynamicDataSourceContextHolder.setContextKey("数据源名称")
- */
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- public class DynamicDataSource extends AbstractRoutingDataSource {
- //备份所有数据源信息,
- private Map<Object, Object> defineTargetDataSources;
-
- @Override
- protected Object determineCurrentLookupKey() {
- return DynamicDataSourceHolder.getDynamicDataSourceKey();
- }
- }
- package com.skyable.monitor.config.datasource;
-
- import lombok.extern.slf4j.Slf4j;
-
- /**
- * 数据源切换处理
- *
- * @author zhangyu
- */
- @Slf4j
- public class DynamicDataSourceHolder {
- /**
- * 保存动态数据源名称
- */
- private static final ThreadLocal<String> DYNAMIC_DATASOURCE_KEY = new ThreadLocal<>();
-
- /**
- * 设置/切换数据源,决定当前线程使用哪个数据源
- */
- public static void setDynamicDataSourceKey(String key){
- log.info("数据源切换为:{}",key);
- DYNAMIC_DATASOURCE_KEY.set(key);
- }
-
- /**
- * 获取动态数据源名称,默认使用mater数据源
- */
- public static String getDynamicDataSourceKey(){
- String key = DYNAMIC_DATASOURCE_KEY.get();
- return key == null ? CommonConstant.MASTER : key;
- }
-
- /**
- * 移除当前数据源
- */
- public static void removeDynamicDataSourceKey(){
- log.info("移除数据源:{}",DYNAMIC_DATASOURCE_KEY.get());
- DYNAMIC_DATASOURCE_KEY.remove();
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。