当前位置:   article > 正文

starRocks配置两个数据源的多个IP进行访问数据库查询_starrocks jdbc

starrocks jdbc

1、yml文件配置

注意mysql为master

  1. datasource:
  2. mysql:
  3. master:
  4. type: com.alibaba.druid.pool.DruidDataSource
  5. driver-class-name: com.mysql.cj.jdbc.Driver
  6. url: jdbc:mysql://192.168.110.1222:3306/sdkjoy-db?characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
  7. username: root
  8. password:
  9. starrocks:
  10. type: com.alibaba.druid.pool.DruidDataSource
  11. driver-class-name: com.mysql.cj.jdbc.Driver
  12. 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
  13. addr: 192.168.110.1111:9030,192.168.110.12222:9030,192.168.110.1333:9030
  14. http:
  15. head: http://
  16. port: 8030
  17. username:
  18. password:

2.config文件指定StarRocks的IP

因为mysql给定了定时任务,项目启动必须访问要以mysql为master

  1. package com.skyable.monitor.config.datasource;
  2. import com.alibaba.druid.pool.DruidDataSource;
  3. import com.skyable.monitor.mapper.mysql.ClusterMapper;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Component;
  6. import java.util.ArrayList;
  7. import java.util.HashMap;
  8. import java.util.List;
  9. import java.util.Objects;
  10. /**
  11. * Description:
  12. *
  13. * @author
  14. * @date: 2023-02-21-13:55
  15. */
  16. @Component
  17. public class StarrocksDatasource {
  18. @Autowired private DataSourceUtil dataSourceUtil;
  19. @Autowired private ClusterMapper clusterMapper;
  20. /**
  21. * 连接starRocks数据源
  22. *
  23. * @param clusterId
  24. * @return
  25. */
  26. public Boolean datasource(Integer clusterId) {
  27. HashMap<String, String> map = new HashMap(4);
  28. List<String> addr = clusterMapper.selectIp(clusterId);
  29. List<String> result = new ArrayList<>();
  30. for (String s : addr) {
  31. StringBuilder stringBuilder = new StringBuilder();
  32. StringBuilder append = stringBuilder.append(s).append(":").append("9030");
  33. result.add(append.toString());
  34. }
  35. String ip = String.join(",", result);
  36. map.put("type", "com.alibaba.druid.pool.DruidDataSource");
  37. map.put("driver-class-name", "com.mysql.cj.jdbc.Driver");
  38. map.put(
  39. "url",
  40. "jdbc:mysql:loadbalance://"
  41. + ip
  42. + "?useUnicode=true&autoReconnect=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai");
  43. map.put("addr", ip);
  44. map.put("username", "root");
  45. map.put("password", "");
  46. DataSourceInfo dataSourceInfo = new DataSourceInfo();
  47. dataSourceInfo.setUrl(map.get("url"));
  48. dataSourceInfo.setDatasourceKey(String.valueOf(clusterId));
  49. dataSourceInfo.setUserName(map.get("username"));
  50. dataSourceInfo.setPassword(map.get("password"));
  51. DruidDataSource druidDataSource = dataSourceUtil.createDataSourceConnection(dataSourceInfo);
  52. if (Objects.nonNull(druidDataSource)) {
  53. dataSourceUtil.addDefineDynamicDataSource(druidDataSource, dataSourceInfo.getDatasourceKey());
  54. DynamicDataSourceHolder.setDynamicDataSourceKey(String.valueOf(clusterId));
  55. }
  56. return true;
  57. }
  58. }
  1. package com.skyable.monitor.config.datasource;
  2. import org.springframework.beans.factory.InitializingBean;
  3. import org.springframework.jdbc.datasource.AbstractDataSource;
  4. import org.springframework.jdbc.datasource.lookup.DataSourceLookup;
  5. import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
  6. import org.springframework.lang.Nullable;
  7. import org.springframework.util.Assert;
  8. import org.springframework.util.CollectionUtils;
  9. import javax.sql.DataSource;
  10. import java.sql.Connection;
  11. import java.sql.SQLException;
  12. import java.util.Map;
  13. public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
  14. //目标数据源map集合,存储将要切换的多数据源bean信息
  15. @Nullable
  16. private Map<Object, Object> targetDataSources;
  17. //未指定数据源时的默认数据源对象
  18. @Nullable
  19. private Object defaultTargetDataSource;
  20. private boolean lenientFallback = true;
  21. //数据源查找接口,通过该接口的getDataSource(String dataSourceName)获取数据源信息
  22. private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
  23. //解析targetDataSources之后的DataSource的map集合
  24. @Nullable
  25. private Map<Object, DataSource> resolvedDataSources;
  26. @Nullable
  27. private DataSource resolvedDefaultDataSource;
  28. @Override
  29. //将targetDataSources的内容转化一下放到resolvedDataSources中,将defaultTargetDataSource转为DataSource赋值给resolvedDefaultDataSource
  30. public void afterPropertiesSet() {
  31. //如果目标数据源为空,会抛出异常,在系统配置时应至少传入一个数据源
  32. if (this.targetDataSources == null) {
  33. throw new IllegalArgumentException("Property 'targetDataSources' is required");
  34. } else {
  35. //初始化resolvedDataSources的大小
  36. this.resolvedDataSources = CollectionUtils.newHashMap(this.targetDataSources.size());
  37. //遍历目标数据源信息map集合,对其中的key,value进行解析
  38. this.targetDataSources.forEach((key, value) -> {
  39. //resolveSpecifiedLookupKey方法没有做任何处理,只是将key继续返回
  40. Object lookupKey = this.resolveSpecifiedLookupKey(key);
  41. //将目标数据源map集合中的value值(德鲁伊数据源信息)转为DataSource类型
  42. DataSource dataSource = this.resolveSpecifiedDataSource(value);
  43. //将解析之后的key,value放入resolvedDataSources集合中
  44. this.resolvedDataSources.put(lookupKey, dataSource);
  45. });
  46. if (this.defaultTargetDataSource != null) {
  47. //将默认目标数据源信息解析并赋值给resolvedDefaultDataSource
  48. this.resolvedDefaultDataSource = this.resolveSpecifiedDataSource(this.defaultTargetDataSource);
  49. }
  50. }
  51. }
  52. protected Object resolveSpecifiedLookupKey(Object lookupKey) {
  53. return lookupKey;
  54. }
  55. protected DataSource resolveSpecifiedDataSource(Object dataSource) throws IllegalArgumentException {
  56. if (dataSource instanceof DataSource) {
  57. return (DataSource)dataSource;
  58. } else if (dataSource instanceof String) {
  59. return this.dataSourceLookup.getDataSource((String)dataSource);
  60. } else {
  61. throw new IllegalArgumentException("Illegal data source value - only [javax.sql.DataSource] and String supported: " + dataSource);
  62. }
  63. }
  64. @Override
  65. //因为AbstractRoutingDataSource继承AbstractDataSource,而AbstractDataSource实现了DataSource接口,所有存在获取数据源连接的方法
  66. public Connection getConnection() throws SQLException {
  67. return this.determineTargetDataSource().getConnection();
  68. }
  69. @Override
  70. public Connection getConnection(String username, String password) throws SQLException {
  71. return this.determineTargetDataSource().getConnection(username, password);
  72. }
  73. protected DataSource determineTargetDataSource() {
  74. Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
  75. //调用实现类中重写的determineCurrentLookupKey方法拿到当前线程要使用的数据源的名称
  76. Object lookupKey = this.determineCurrentLookupKey();
  77. //去解析之后的数据源信息集合中查询该数据源是否存在,如果没有拿到则使用默认数据源resolvedDefaultDataSource
  78. DataSource dataSource = (DataSource)this.resolvedDataSources.get(lookupKey);
  79. if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
  80. dataSource = this.resolvedDefaultDataSource;
  81. }
  82. if (dataSource == null) {
  83. throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
  84. } else {
  85. return dataSource;
  86. }
  87. }
  88. @Nullable
  89. protected abstract Object determineCurrentLookupKey();
  90. }

  1. package com.skyable.monitor.config.datasource;
  2. /**
  3. * @Description: 动态数据源常量类
  4. *
  5. */
  6. public class CommonConstant {
  7. /**
  8. * 默认数据源标识
  9. */
  10. public static final String MASTER = "master";
  11. }
  1. package com.skyable.monitor.config.datasource;
  2. import lombok.Data;
  3. @Data
  4. public class DataSourceInfo {
  5. private String url;
  6. private String userName;
  7. private String password;
  8. private String datasourceKey;
  9. }
  1. package com.skyable.monitor.config.datasource;
  2. import com.alibaba.druid.pool.DruidDataSource;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.springframework.stereotype.Component;
  5. import javax.annotation.Resource;
  6. import java.sql.SQLException;
  7. import java.util.Map;
  8. /**
  9. * @Description: 数据源工具类
  10. * @Date 2022/8/18 17:20
  11. *
  12. */
  13. @Slf4j
  14. @Component
  15. public class DataSourceUtil {
  16. @Resource
  17. DynamicDataSource dynamicDataSource;
  18. /**
  19. * @Description: 根据传递的数据源信息测试数据库连接
  20. * @Author zhangyu
  21. */
  22. public DruidDataSource createDataSourceConnection(DataSourceInfo dataSourceInfo) {
  23. DruidDataSource druidDataSource = new DruidDataSource();
  24. druidDataSource.setUrl(dataSourceInfo.getUrl());
  25. druidDataSource.setUsername(dataSourceInfo.getUserName());
  26. druidDataSource.setPassword(dataSourceInfo.getPassword());
  27. druidDataSource.setBreakAfterAcquireFailure(true);
  28. druidDataSource.setConnectionErrorRetryAttempts(0);
  29. try {
  30. druidDataSource.getConnection(2000);
  31. log.info("数据源连接成功");
  32. return druidDataSource;
  33. } catch (SQLException throwables) {
  34. log.error("数据源 {} 连接失败,用户名:{},密码 {}",dataSourceInfo.getUrl(),dataSourceInfo.getUserName(),dataSourceInfo.getPassword());
  35. return null;
  36. }
  37. }
  38. /**
  39. * @Description: 将新增的数据源加入到备份数据源map中
  40. * @Author zhangyu
  41. */
  42. public void addDefineDynamicDataSource(DruidDataSource druidDataSource, String dataSourceName){
  43. Map<Object, Object> defineTargetDataSources = dynamicDataSource.getDefineTargetDataSources();
  44. defineTargetDataSources.put(dataSourceName, druidDataSource);
  45. dynamicDataSource.setTargetDataSources(defineTargetDataSources);
  46. dynamicDataSource.afterPropertiesSet();
  47. }
  48. }
  1. package com.skyable.monitor.config.datasource;
  2. import com.alibaba.druid.pool.DruidDataSource;
  3. import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
  4. import org.mybatis.spring.annotation.MapperScan;
  5. import org.springframework.boot.context.properties.ConfigurationProperties;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.context.annotation.Primary;
  9. import javax.sql.DataSource;
  10. import java.util.HashMap;
  11. import java.util.Map;
  12. @Configuration
  13. @MapperScan("com.skyable.monitor.mapper")
  14. public class DruidConfig {
  15. @Bean(name = CommonConstant.MASTER)
  16. @ConfigurationProperties("spring.datasource.mysql.master")
  17. public DruidDataSource masterDataSource()
  18. {
  19. DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
  20. return dataSource;
  21. }
  22. @Bean(name = "starrocksDataSource")
  23. @ConfigurationProperties("spring.datasource.starrocks")
  24. public DruidDataSource deafultStarRocksDataSource()
  25. {
  26. DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
  27. return dataSource;
  28. }
  29. @Bean
  30. @Primary
  31. public DynamicDataSource dynamicDataSource()
  32. {
  33. Map<Object, Object> dataSourceMap = new HashMap<>(2);
  34. dataSourceMap.put(CommonConstant.MASTER,masterDataSource());
  35. //设置动态数据源
  36. DynamicDataSource dynamicDataSource = new DynamicDataSource();
  37. dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
  38. dynamicDataSource.setTargetDataSources(dataSourceMap);
  39. //将数据源信息备份在defineTargetDataSources中
  40. dynamicDataSource.setDefineTargetDataSources(dataSourceMap);
  41. return dynamicDataSource;
  42. }
  43. }
  1. package com.skyable.monitor.config.datasource;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
  6. import java.util.Map;
  7. /**
  8. * 动态数据源
  9. * 调用AddDefineDataSource组件的addDefineDynamicDataSource()方法,获取原来targetdatasources的map,并将新的数据源信息添加到map中,并替换targetdatasources中的map
  10. * 切换数据源时可以使用@DataSource(value = "数据源名称"),或者DynamicDataSourceContextHolder.setContextKey("数据源名称")
  11. */
  12. @Data
  13. @AllArgsConstructor
  14. @NoArgsConstructor
  15. public class DynamicDataSource extends AbstractRoutingDataSource {
  16. //备份所有数据源信息,
  17. private Map<Object, Object> defineTargetDataSources;
  18. @Override
  19. protected Object determineCurrentLookupKey() {
  20. return DynamicDataSourceHolder.getDynamicDataSourceKey();
  21. }
  22. }

  1. package com.skyable.monitor.config.datasource;
  2. import lombok.extern.slf4j.Slf4j;
  3. /**
  4. * 数据源切换处理
  5. *
  6. * @author zhangyu
  7. */
  8. @Slf4j
  9. public class DynamicDataSourceHolder {
  10. /**
  11. * 保存动态数据源名称
  12. */
  13. private static final ThreadLocal<String> DYNAMIC_DATASOURCE_KEY = new ThreadLocal<>();
  14. /**
  15. * 设置/切换数据源,决定当前线程使用哪个数据源
  16. */
  17. public static void setDynamicDataSourceKey(String key){
  18. log.info("数据源切换为:{}",key);
  19. DYNAMIC_DATASOURCE_KEY.set(key);
  20. }
  21. /**
  22. * 获取动态数据源名称,默认使用mater数据源
  23. */
  24. public static String getDynamicDataSourceKey(){
  25. String key = DYNAMIC_DATASOURCE_KEY.get();
  26. return key == null ? CommonConstant.MASTER : key;
  27. }
  28. /**
  29. * 移除当前数据源
  30. */
  31. public static void removeDynamicDataSourceKey(){
  32. log.info("移除数据源:{}",DYNAMIC_DATASOURCE_KEY.get());
  33. DYNAMIC_DATASOURCE_KEY.remove();
  34. }
  35. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/579500
推荐阅读
相关标签
  

闽ICP备14008679号