一.插件实现

  1.插件目录结构

  2.pom依赖

  1. <dependency>
  2. <groupId>com.alibaba.nacos</groupId>
  3. <artifactId>nacos-datasource-plugin</artifactId>
  4. <version>2.2.4</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework</groupId>
  8. <artifactId>spring-jdbc</artifactId>
  9. <version>3.1.3.RELEASE</version>
  10. </dependency>
  11. <!-- 达梦 -->
  12. <dependency>
  13. <groupId>com.dameng</groupId>
  14. <artifactId>Dm8JdbcDriver18</artifactId>
  15. <version>8.1.1.49</version>
  16. </dependency>
  17. <!-- 瀚高 -->
  18. <dependency>
  19. <groupId>com.highgo</groupId>
  20. <artifactId>HgdbJdbc</artifactId>
  21. <version>6.2.2</version>
  22. </dependency>
  23. <!--人大金仓 -->
  24. <dependency>
  25. <groupId>com.kingbase</groupId>
  26. <artifactId>kingbase8</artifactId>
  27. <version>8.2.0</version>
  28. </dependency>

  3.代码实现

  3.1.DataSourceConstant

  1. public class DataSourceConstant {
  2. public static final String MYSQL = "mysql";
  3.  
  4. public static final String DERBY = "derby";
  5.  
  6. public static final String DM="dm";
  7.  
  8. public static final String HIGHGO="highgo";
  9.  
  10. public static final String KINGBASE="kingbase";
  11.  
  12. }

  3.2.公共方法

   3.2.1.AbstractConfigInfoAggrMapperCommon

  1. package com.alibaba.nacos.plugin.datasource.impl.common;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
  4. import com.alibaba.nacos.plugin.datasource.mapper.AbstractMapper;
  5. import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoAggrMapper;
  6.  
  7. public abstract class AbstractConfigInfoAggrMapperCommon extends AbstractMapper implements ConfigInfoAggrMapper {
  8.  
  9. @Override
  10. public String batchRemoveAggr(int datumSize) {
  11. final StringBuilder placeholderString = new StringBuilder();
  12. for (int i = 0; i < datumSize; i++) {
  13. if (i != 0) {
  14. placeholderString.append(", ");
  15. }
  16. placeholderString.append('?');
  17. }
  18. return "DELETE FROM config_info_aggr WHERE data_id = ? AND group_id = ? AND tenant_id = ? AND datum_id IN ("
  19. + placeholderString + ")";
  20. }
  21.  
  22. @Override
  23. public String aggrConfigInfoCount(int size, boolean isIn) {
  24. StringBuilder sql = new StringBuilder(
  25. "SELECT count(*) FROM config_info_aggr WHERE data_id = ? AND group_id = ? AND tenant_id = ? AND datum_id");
  26. if (isIn) {
  27. sql.append(" IN (");
  28. } else {
  29. sql.append(" NOT IN (");
  30. }
  31. for (int i = 0; i < size; i++) {
  32. if (i > 0) {
  33. sql.append(", ");
  34. }
  35. sql.append('?');
  36. }
  37. sql.append(')');
  38.  
  39. return sql.toString();
  40. }
  41.  
  42. public String findConfigInfoAggrIsOrdered() {
  43. return "SELECT data_id,group_id,tenant_id,datum_id,app_name,content FROM "
  44. + "config_info_aggr WHERE data_id = ? AND group_id = ? AND tenant_id = ? ORDER BY datum_id";
  45. }
  46.  
  47. public String findConfigInfoAggrByPageFetchRows(int startRow, int pageSize) {
  48. return "SELECT data_id,group_id,tenant_id,datum_id,app_name,content FROM config_info_aggr WHERE data_id= ? AND "
  49. + "group_id= ? AND tenant_id= ? ORDER BY datum_id LIMIT " + pageSize + " OFFSET " + startRow;
  50. }
  51.  
  52. public String findAllAggrGroupByDistinct() {
  53. return "SELECT DISTINCT data_id, group_id, tenant_id FROM config_info_aggr";
  54. }
  55.  
  56. public String getTableName() {
  57. return TableConstant.CONFIG_INFO_AGGR;
  58. }
  59.  
  60. }
   3.2.2.AbstractConfigInfoBetaMapperCommon

  1. package com.alibaba.nacos.plugin.datasource.impl.common;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
  4. import com.alibaba.nacos.plugin.datasource.mapper.AbstractMapper;
  5. import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoBetaMapper;
  6.  
  7. public abstract class AbstractConfigInfoBetaMapperCommon extends AbstractMapper implements ConfigInfoBetaMapper {
  8.  
  9. public String updateConfigInfo4BetaCas() {
  10. return "UPDATE config_info_beta SET content = ?,md5 = ?,beta_ips = ?,src_ip = ?,src_user = ?,gmt_modified = ?,app_name = ? "
  11. + "WHERE data_id = ? AND group_id = ? AND tenant_id = ? AND (md5 = ? or md5 is null or md5 = '')";
  12. }
  13.  
  14. public String findAllConfigInfoBetaForDumpAllFetchRows(int startRow, int pageSize) {
  15. return " SELECT t.id,data_id,group_id,tenant_id,app_name,content,md5,gmt_modified,beta_ips,encrypted_data_key "
  16. + " FROM ( SELECT id FROM config_info_beta ORDER BY id LIMIT " + pageSize + " OFFSET " + startRow
  17. + " )" + " g, config_info_beta t WHERE g.id = t.id ";
  18. }
  19.  
  20. public String getTableName() {
  21. return TableConstant.CONFIG_INFO_BETA;
  22. }
  23. }
   3.2.3.AbstractConfigInfoTagMapperCommon

  1. package com.alibaba.nacos.plugin.datasource.impl.common;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
  4. import com.alibaba.nacos.plugin.datasource.mapper.AbstractMapper;
  5. import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoTagMapper;
  6.  
  7. public abstract class AbstractConfigInfoTagMapperCommon extends AbstractMapper implements ConfigInfoTagMapper {
  8.  
  9. public String updateConfigInfo4TagCas() {
  10. return "UPDATE config_info_tag SET content = ?, md5 = ?, src_ip = ?,src_user = ?,gmt_modified = ?,app_name = ? "
  11. + "WHERE data_id = ? AND group_id = ? AND tenant_id = ? AND tag_id = ? AND (md5 = ? OR md5 IS NULL OR md5 = '')";
  12. }
  13.  
  14. public String findAllConfigInfoTagForDumpAllFetchRows(int startRow, int pageSize) {
  15. return " SELECT t.id,data_id,group_id,tenant_id,tag_id,app_name,content,md5,gmt_modified "
  16. + " FROM ( SELECT id FROM config_info_tag ORDER BY id LIMIT " + pageSize + " OFFSET " + startRow
  17. + " ) " + "g, config_info_tag t WHERE g.id = t.id ";
  18. }
  19.  
  20. public String getTableName() {
  21. return TableConstant.CONFIG_INFO_TAG;
  22. }
  23.  
  24. }
   3.2.4.AbstractConfigTagsRelationMapperCommon

  1. package com.alibaba.nacos.plugin.datasource.impl.common;
  2.  
  3. import com.alibaba.nacos.common.utils.StringUtils;
  4. import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
  5. import com.alibaba.nacos.plugin.datasource.mapper.AbstractMapper;
  6. import com.alibaba.nacos.plugin.datasource.mapper.ConfigTagsRelationMapper;
  7.  
  8. import java.util.Map;
  9.  
  10. public abstract class AbstractConfigTagsRelationMapperCommon extends AbstractMapper implements ConfigTagsRelationMapper {
  11.  
  12. public String findConfigInfo4PageCountRows(final Map<String, String> params, final int tagSize) {
  13. final String appName = params.get("appName");
  14. final String dataId = params.get("dataId");
  15. final String group = params.get("group");
  16. StringBuilder where = new StringBuilder(" WHERE ");
  17. final String sqlCount = "SELECT count(*) FROM config_info a LEFT JOIN config_tags_relation b ON a.id=b.id";
  18. where.append(" a.tenant_id=? ");
  19. if (StringUtils.isNotBlank(dataId)) {
  20. where.append(" AND a.data_id=? ");
  21. }
  22. if (StringUtils.isNotBlank(group)) {
  23. where.append(" AND a.group_id=? ");
  24. }
  25. if (StringUtils.isNotBlank(appName)) {
  26. where.append(" AND a.app_name=? ");
  27. }
  28. where.append(" AND b.tag_name IN (");
  29. for (int i = 0; i < tagSize; i++) {
  30. if (i != 0) {
  31. where.append(", ");
  32. }
  33. where.append('?');
  34. }
  35. where.append(") ");
  36. return sqlCount + where;
  37. }
  38.  
  39. public String findConfigInfo4PageFetchRows(Map<String, String> params, int tagSize, int startRow, int pageSize) {
  40. final String appName = params.get("appName");
  41. final String dataId = params.get("dataId");
  42. final String group = params.get("group");
  43. StringBuilder where = new StringBuilder(" WHERE ");
  44. final String sql = "SELECT a.id,a.data_id,a.group_id,a.tenant_id,a.app_name,a.content FROM config_info a LEFT JOIN "
  45. + "config_tags_relation b ON a.id=b.id";
  46.  
  47. where.append(" a.tenant_id=? ");
  48.  
  49. if (StringUtils.isNotBlank(dataId)) {
  50. where.append(" AND a.data_id=? ");
  51. }
  52. if (StringUtils.isNotBlank(group)) {
  53. where.append(" AND a.group_id=? ");
  54. }
  55. if (StringUtils.isNotBlank(appName)) {
  56. where.append(" AND a.app_name=? ");
  57. }
  58.  
  59. where.append(" AND b.tag_name IN (");
  60. for (int i = 0; i < tagSize; i++) {
  61. if (i != 0) {
  62. where.append(", ");
  63. }
  64. where.append('?');
  65. }
  66. where.append(") ");
  67. return sql + where + " LIMIT " + pageSize + " OFFSET " + startRow;
  68. }
  69.  
  70. public String findConfigInfoLike4PageCountRows(final Map<String, String> params, int tagSize) {
  71. final String appName = params.get("appName");
  72. final String content = params.get("content");
  73. final String dataId = params.get("dataId");
  74. final String group = params.get("group");
  75. StringBuilder where = new StringBuilder(" WHERE ");
  76. final String sqlCountRows = "SELECT count(*) FROM config_info a LEFT JOIN config_tags_relation b ON a.id=b.id ";
  77.  
  78. where.append(" a.tenant_id LIKE ? ");
  79. if (!StringUtils.isBlank(dataId)) {
  80. where.append(" AND a.data_id LIKE ? ");
  81. }
  82. if (!StringUtils.isBlank(group)) {
  83. where.append(" AND a.group_id LIKE ? ");
  84. }
  85. if (!StringUtils.isBlank(appName)) {
  86. where.append(" AND a.app_name = ? ");
  87. }
  88. if (!StringUtils.isBlank(content)) {
  89. where.append(" AND a.content LIKE ? ");
  90. }
  91.  
  92. where.append(" AND b.tag_name IN (");
  93. for (int i = 0; i < tagSize; i++) {
  94. if (i != 0) {
  95. where.append(", ");
  96. }
  97. where.append('?');
  98. }
  99. where.append(") ");
  100. return sqlCountRows + where;
  101. }
  102.  
  103. public String findConfigInfoLike4PageFetchRows(final Map<String, String> params, int tagSize, int startRow,
  104. int pageSize) {
  105. final String appName = params.get("appName");
  106. final String content = params.get("content");
  107. final String dataId = params.get("dataId");
  108. final String group = params.get("group");
  109. StringBuilder where = new StringBuilder(" WHERE ");
  110. final String sqlFetchRows = "SELECT a.id,a.data_id,a.group_id,a.tenant_id,a.app_name,a.content "
  111. + "FROM config_info a LEFT JOIN config_tags_relation b ON a.id=b.id ";
  112.  
  113. where.append(" a.tenant_id LIKE ? ");
  114. if (!StringUtils.isBlank(dataId)) {
  115. where.append(" AND a.data_id LIKE ? ");
  116. }
  117. if (!StringUtils.isBlank(group)) {
  118. where.append(" AND a.group_id LIKE ? ");
  119. }
  120. if (!StringUtils.isBlank(appName)) {
  121. where.append(" AND a.app_name = ? ");
  122. }
  123. if (!StringUtils.isBlank(content)) {
  124. where.append(" AND a.content LIKE ? ");
  125. }
  126.  
  127. where.append(" AND b.tag_name IN (");
  128. for (int i = 0; i < tagSize; i++) {
  129. if (i != 0) {
  130. where.append(", ");
  131. }
  132. where.append('?');
  133. }
  134. where.append(") ");
  135. return sqlFetchRows + where + " LIMIT " + startRow + "," + pageSize;
  136. }
  137.  
  138. public String getTableName() {
  139. return TableConstant.CONFIG_TAGS_RELATION;
  140. }
  141.  
  142. }
   3.2.5.AbstractGroupCapacityMapperCommon

  1. package com.alibaba.nacos.plugin.datasource.impl.common;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
  4. import com.alibaba.nacos.plugin.datasource.mapper.AbstractMapper;
  5. import com.alibaba.nacos.plugin.datasource.mapper.GroupCapacityMapper;
  6.  
  7. public abstract class AbstractGroupCapacityMapperCommon extends AbstractMapper implements GroupCapacityMapper {
  8.  
  9. public String insertIntoSelect() {
  10. return "INSERT INTO group_capacity (group_id, quota, `usage`, `max_size`, max_aggr_count, max_aggr_size,gmt_create,"
  11. + " gmt_modified) SELECT ?, ?, count(*), ?, ?, ?, ?, ? FROM config_info";
  12. }
  13.  
  14. public String insertIntoSelectByWhere() {
  15. return "INSERT INTO group_capacity (group_id, quota,`usage`, `max_size`, max_aggr_count, max_aggr_size, gmt_create,"
  16. + " gmt_modified) SELECT ?, ?, count(*), ?, ?, ?, ?, ? FROM config_info WHERE group_id=? AND tenant_id = ''";
  17. }
  18.  
  19. public String incrementUsageByWhereQuotaEqualZero() {
  20. return "UPDATE group_capacity SET `usage` = `usage` + 1, gmt_modified = ? WHERE group_id = ? AND `usage` < ? AND quota = 0";
  21. }
  22.  
  23. public String incrementUsageByWhereQuotaNotEqualZero() {
  24. return "UPDATE group_capacity SET `usage` = `usage` + 1, gmt_modified = ? WHERE group_id = ? AND `usage` < quota AND quota != 0";
  25. }
  26.  
  27. public String incrementUsageByWhere() {
  28. return "UPDATE group_capacity SET `usage` = `usage` + 1, gmt_modified = ? WHERE group_id = ?";
  29. }
  30.  
  31. public String decrementUsageByWhere() {
  32. return "UPDATE group_capacity SET `usage` = `usage` - 1, gmt_modified = ? WHERE group_id = ? AND `usage` > 0";
  33. }
  34.  
  35. public String updateUsage() {
  36. return "UPDATE group_capacity SET `usage` = (SELECT count(*) FROM config_info), gmt_modified = ? WHERE group_id = ?";
  37. }
  38.  
  39. public String updateUsageByWhere() {
  40. return "UPDATE group_capacity SET `usage` = (SELECT count(*) FROM config_info WHERE group_id=? AND tenant_id = ''),"
  41. + " gmt_modified = ? WHERE group_id= ?";
  42. }
  43.  
  44. public String selectGroupInfoBySize() {
  45. return "SELECT id, group_id FROM group_capacity WHERE id > ? LIMIT ?";
  46. }
  47.  
  48. public String getTableName() {
  49. return TableConstant.GROUP_CAPACITY;
  50. }
  51.  
  52. }
   3.2.6.AbstractHistoryConfigInfoMapperCommon

  1. package com.alibaba.nacos.plugin.datasource.impl.common;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
  4. import com.alibaba.nacos.plugin.datasource.mapper.AbstractMapper;
  5. import com.alibaba.nacos.plugin.datasource.mapper.HistoryConfigInfoMapper;
  6.  
  7. public abstract class AbstractHistoryConfigInfoMapperCommon extends AbstractMapper implements HistoryConfigInfoMapper {
  8.  
  9. public String removeConfigHistory() {
  10. return "DELETE FROM his_config_info WHERE gmt_modified < ? LIMIT ?";
  11. }
  12.  
  13. public String findConfigHistoryCountByTime() {
  14. return "SELECT count(*) FROM his_config_info WHERE gmt_modified < ?";
  15. }
  16.  
  17. public String findDeletedConfig() {
  18. return "SELECT DISTINCT data_id, group_id, tenant_id FROM his_config_info WHERE op_type = 'D' AND gmt_modified >= ? AND gmt_modified <= ?";
  19. }
  20.  
  21. public String findConfigHistoryFetchRows() {
  22. return "SELECT nid,data_id,group_id,tenant_id,app_name,src_ip,src_user,op_type,gmt_create,gmt_modified FROM his_config_info "
  23. + "WHERE data_id = ? AND group_id = ? AND tenant_id = ? ORDER BY nid DESC";
  24. }
  25.  
  26. public String detailPreviousConfigHistory() {
  27. return "SELECT nid,data_id,group_id,tenant_id,app_name,content,md5,src_user,src_ip,op_type,gmt_create,gmt_modified "
  28. + "FROM his_config_info WHERE nid = (SELECT max(nid) FROM his_config_info WHERE id = ?) ";
  29. }
  30.  
  31. public String pageFindConfigHistoryFetchRows(int pageNo, int pageSize) {
  32. final int offset = (pageNo - 1) * pageSize;
  33. final int limit = pageSize;
  34. return "SELECT nid,data_id,group_id,tenant_id,app_name,src_ip,src_user,op_type,gmt_create,gmt_modified FROM his_config_info "
  35. + "WHERE data_id = ? AND group_id = ? AND tenant_id = ? ORDER BY nid DESC LIMIT " + offset + "," + limit;
  36. }
  37.  
  38. public String getTableName() {
  39. return TableConstant.HIS_CONFIG_INFO;
  40. }
  41.  
  42. }
   3.2.7.AbstractTenantCapacityMapperCommon

  1. package com.alibaba.nacos.plugin.datasource.impl.common;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
  4. import com.alibaba.nacos.plugin.datasource.mapper.AbstractMapper;
  5. import com.alibaba.nacos.plugin.datasource.mapper.TenantCapacityMapper;
  6.  
  7. public abstract class AbstractTenantCapacityMapperCommon extends AbstractMapper implements TenantCapacityMapper {
  8.  
  9. public String incrementUsageWithDefaultQuotaLimit() {
  10. return "UPDATE tenant_capacity SET `usage` = `usage` + 1, gmt_modified = ? WHERE tenant_id = ? AND `usage` <"
  11. + " ? AND quota = 0";
  12. }
  13.  
  14. public String incrementUsageWithQuotaLimit() {
  15. return "UPDATE tenant_capacity SET `usage` = `usage` + 1, gmt_modified = ? WHERE tenant_id = ? AND `usage` < "
  16. + "quota AND quota != 0";
  17. }
  18.  
  19. public String incrementUsage() {
  20. return "UPDATE tenant_capacity SET `usage` = `usage` + 1, gmt_modified = ? WHERE tenant_id = ?";
  21. }
  22.  
  23. public String decrementUsage() {
  24. return "UPDATE tenant_capacity SET `usage` = `usage` - 1, gmt_modified = ? WHERE tenant_id = ? AND `usage` > 0";
  25. }
  26.  
  27. public String correctUsage() {
  28. return "UPDATE tenant_capacity SET `usage` = (SELECT count(*) FROM config_info WHERE tenant_id = ?), "
  29. + "gmt_modified = ? WHERE tenant_id = ?";
  30. }
  31.  
  32. public String getCapacityList4CorrectUsage() {
  33. return "SELECT id, tenant_id FROM tenant_capacity WHERE id>? LIMIT ?";
  34. }
  35.  
  36. public String insertTenantCapacity() {
  37. return "INSERT INTO tenant_capacity (tenant_id, quota, `usage`, `max_size`, max_aggr_count, max_aggr_size, "
  38. + "gmt_create, gmt_modified) SELECT ?, ?, count(*), ?, ?, ?, ?, ? FROM config_info WHERE tenant_id=?;";
  39. }
  40.  
  41. public String getTableName() {
  42. return TableConstant.TENANT_CAPACITY;
  43. }
  44.  
  45. }
   3.2.8.AbstractConfigInfoMapperCommon

  1. package com.alibaba.nacos.plugin.datasource.impl.common;
  2.  
  3. import com.alibaba.nacos.common.utils.CollectionUtils;
  4. import com.alibaba.nacos.common.utils.StringUtils;
  5. import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
  6. import com.alibaba.nacos.plugin.datasource.mapper.AbstractMapper;
  7. import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoMapper;
  8.  
  9. import java.sql.Timestamp;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12. import java.util.Map;
  13.  
  14. public abstract class AbstractConfigInfoMapperCommon extends AbstractMapper implements ConfigInfoMapper {
  15.  
  16. private static final String DATA_ID = "dataId";
  17.  
  18. private static final String GROUP = "group";
  19.  
  20. private static final String APP_NAME = "appName";
  21.  
  22. private static final String CONTENT = "content";
  23.  
  24. private static final String TENANT = "tenant";
  25.  
  26. public String findConfigMaxId() {
  27. return "SELECT MAX(id) FROM config_info";
  28. }
  29.  
  30. public String findAllDataIdAndGroup() {
  31. return "SELECT DISTINCT data_id, group_id FROM config_info";
  32. }
  33.  
  34. public String findConfigInfoByAppCountRows() {
  35. return "SELECT count(*) FROM config_info WHERE tenant_id LIKE ? AND app_name= ?";
  36. }
  37.  
  38. public String findConfigInfoByAppFetchRows(int startRow, int pageSize) {
  39. return "SELECT id,data_id,group_id,tenant_id,app_name,content FROM config_info"
  40. + " WHERE tenant_id LIKE ? AND app_name= ?" + " LIMIT " + pageSize + " OFFSET " + startRow;
  41. }
  42.  
  43. public String configInfoLikeTenantCount() {
  44. return "SELECT count(*) FROM config_info WHERE tenant_id LIKE ?";
  45. }
  46.  
  47. public String getTenantIdList(int startRow, int pageSize) {
  48. return "SELECT tenant_id FROM config_info WHERE tenant_id != '' GROUP BY tenant_id LIMIT " + pageSize
  49. + " OFFSET " + startRow;
  50. }
  51.  
  52. public String getGroupIdList(int startRow, int pageSize) {
  53. return "SELECT group_id FROM config_info WHERE tenant_id ='' GROUP BY group_id LIMIT " + pageSize + " OFFSET "
  54. + startRow;
  55. }
  56.  
  57. public String findAllConfigKey(int startRow, int pageSize) {
  58. return " SELECT data_id,group_id,app_name FROM ( "
  59. + " SELECT id FROM config_info WHERE tenant_id LIKE ? ORDER BY id LIMIT " + pageSize + " OFFSET "
  60. + startRow + " )" + " g, config_info t WHERE g.id = t.id ";
  61. }
  62.  
  63. public String findAllConfigInfoBaseFetchRows(int startRow, int pageSize) {
  64. return "SELECT t.id,data_id,group_id,content,md5"
  65. + " FROM ( SELECT id FROM config_info ORDER BY id LIMIT ?,? ) "
  66. + " g, config_info t WHERE g.id = t.id ";
  67. }
  68.  
  69. public String findAllConfigInfoFragment(int startRow, int pageSize) {
  70. return "SELECT id,data_id,group_id,tenant_id,app_name,content,md5,gmt_modified,type,encrypted_data_key "
  71. + "FROM config_info WHERE id > ? ORDER BY id ASC LIMIT " + pageSize + " OFFSET " + startRow;
  72. }
  73.  
  74. public String findChangeConfig() {
  75. return "SELECT data_id, group_id, tenant_id, app_name, content, gmt_modified,encrypted_data_key "
  76. + "FROM config_info WHERE gmt_modified >= ? AND gmt_modified <= ?";
  77. }
  78.  
  79. public String findChangeConfigCountRows(Map<String, String> params, final Timestamp startTime,
  80. final Timestamp endTime) {
  81. final String tenant = params.get(TENANT);
  82. final String dataId = params.get(DATA_ID);
  83. final String group = params.get(GROUP);
  84. final String appName = params.get(APP_NAME);
  85. final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant;
  86. final String sqlCountRows = "SELECT count(*) FROM config_info WHERE ";
  87. String where = " 1=1 ";
  88. if (!StringUtils.isBlank(dataId)) {
  89. where += " AND data_id LIKE ? ";
  90. }
  91. if (!StringUtils.isBlank(group)) {
  92. where += " AND group_id LIKE ? ";
  93. }
  94.  
  95. if (!StringUtils.isBlank(tenantTmp)) {
  96. where += " AND tenant_id = ? ";
  97. }
  98.  
  99. if (!StringUtils.isBlank(appName)) {
  100. where += " AND app_name = ? ";
  101. }
  102. if (startTime != null) {
  103. where += " AND gmt_modified >=? ";
  104. }
  105. if (endTime != null) {
  106. where += " AND gmt_modified <=? ";
  107. }
  108. return sqlCountRows + where;
  109. }
  110.  
  111. public String findChangeConfigFetchRows(Map<String, String> params, final Timestamp startTime,
  112. final Timestamp endTime, int startRow, int pageSize, long lastMaxId) {
  113. final String tenant = params.get(TENANT);
  114. final String dataId = params.get(DATA_ID);
  115. final String group = params.get(GROUP);
  116. final String appName = params.get(APP_NAME);
  117. final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant;
  118. final String sqlFetchRows = "SELECT id,data_id,group_id,tenant_id,app_name,content,type,md5,gmt_modified FROM config_info WHERE ";
  119. String where = " 1=1 ";
  120. if (!StringUtils.isBlank(dataId)) {
  121. where += " AND data_id LIKE ? ";
  122. }
  123. if (!StringUtils.isBlank(group)) {
  124. where += " AND group_id LIKE ? ";
  125. }
  126.  
  127. if (!StringUtils.isBlank(tenantTmp)) {
  128. where += " AND tenant_id = ? ";
  129. }
  130.  
  131. if (!StringUtils.isBlank(appName)) {
  132. where += " AND app_name = ? ";
  133. }
  134. if (startTime != null) {
  135. where += " AND gmt_modified >=? ";
  136. }
  137. if (endTime != null) {
  138. where += " AND gmt_modified <=? ";
  139. }
  140. return sqlFetchRows + where + " AND id > " + lastMaxId + " ORDER BY id ASC" + " LIMIT " + 0 + " OFFSET "
  141. + pageSize;
  142. }
  143.  
  144. public String listGroupKeyMd5ByPageFetchRows(int startRow, int pageSize) {
  145. return "SELECT t.id,data_id,group_id,tenant_id,app_name,md5,type,gmt_modified,encrypted_data_key FROM "
  146. + "( SELECT id FROM config_info ORDER BY id LIMIT " + pageSize + " OFFSET " + startRow
  147. + " ) g, config_info t WHERE g.id = t.id";
  148. }
  149.  
  150. public String findAllConfigInfo4Export(List<Long> ids, Map<String, String> params) {
  151. String tenant = params.get("tenant");
  152. String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant;
  153. String sql = "SELECT id,data_id,group_id,tenant_id,app_name,content,type,md5,gmt_create,gmt_modified,src_user,src_ip,"
  154. + "c_desc,c_use,effect,c_schema,encrypted_data_key FROM config_info";
  155. StringBuilder where = new StringBuilder(" WHERE ");
  156. List<Object> paramList = new ArrayList<>();
  157. if (!CollectionUtils.isEmpty(ids)) {
  158. where.append(" id IN (");
  159. for (int i = 0; i < ids.size(); i++) {
  160. if (i != 0) {
  161. where.append(", ");
  162. }
  163. where.append('?');
  164. paramList.add(ids.get(i));
  165. }
  166. where.append(") ");
  167. } else {
  168. where.append(" tenant_id= ? ");
  169. paramList.add(tenantTmp);
  170. if (!StringUtils.isBlank(params.get(DATA_ID))) {
  171. where.append(" AND data_id LIKE ? ");
  172. }
  173. if (StringUtils.isNotBlank(params.get(GROUP))) {
  174. where.append(" AND group_id= ? ");
  175. }
  176. if (StringUtils.isNotBlank(params.get(APP_NAME))) {
  177. where.append(" AND app_name= ? ");
  178. }
  179. }
  180. return sql + where;
  181. }
  182.  
  183. public String findConfigInfoBaseLikeCountRows(Map<String, String> params) {
  184. final String sqlCountRows = "SELECT count(*) FROM config_info WHERE ";
  185. String where = " 1=1 AND tenant_id='' ";
  186.  
  187. if (!StringUtils.isBlank(params.get(DATA_ID))) {
  188. where += " AND data_id LIKE ? ";
  189. }
  190. if (!StringUtils.isBlank(params.get(GROUP))) {
  191. where += " AND group_id LIKE ";
  192. }
  193. if (!StringUtils.isBlank(params.get(CONTENT))) {
  194. where += " AND content LIKE ? ";
  195. }
  196. return sqlCountRows + where;
  197. }
  198.  
  199. public String findConfigInfoBaseLikeFetchRows(Map<String, String> params, int startRow, int pageSize) {
  200. final String sqlFetchRows = "SELECT id,data_id,group_id,tenant_id,content FROM config_info WHERE ";
  201. String where = " 1=1 AND tenant_id='' ";
  202. if (!StringUtils.isBlank(params.get(DATA_ID))) {
  203. where += " AND data_id LIKE ? ";
  204. }
  205. if (!StringUtils.isBlank(params.get(GROUP))) {
  206. where += " AND group_id LIKE ";
  207. }
  208. if (!StringUtils.isBlank(params.get(CONTENT))) {
  209. where += " AND content LIKE ? ";
  210. }
  211. return sqlFetchRows + where + " LIMIT " + startRow + "," + pageSize;
  212. }
  213.  
  214. public String findConfigInfo4PageCountRows(Map<String, String> params) {
  215. final String appName = params.get(APP_NAME);
  216. final String dataId = params.get(DATA_ID);
  217. final String group = params.get(GROUP);
  218. final String sqlCount = "SELECT count(*) FROM config_info";
  219. StringBuilder where = new StringBuilder(" WHERE ");
  220. where.append(" tenant_id=? ");
  221. if (StringUtils.isNotBlank(dataId)) {
  222. where.append(" AND data_id=? ");
  223. }
  224. if (StringUtils.isNotBlank(group)) {
  225. where.append(" AND group_id=? ");
  226. }
  227. if (StringUtils.isNotBlank(appName)) {
  228. where.append(" AND app_name=? ");
  229. }
  230. return sqlCount + where;
  231. }
  232.  
  233. public String findConfigInfo4PageFetchRows(Map<String, String> params, int startRow, int pageSize) {
  234. final String appName = params.get(APP_NAME);
  235. final String dataId = params.get(DATA_ID);
  236. final String group = params.get(GROUP);
  237. final String sql = "SELECT id,data_id,group_id,tenant_id,app_name,content,type,encrypted_data_key FROM config_info";
  238. StringBuilder where = new StringBuilder(" WHERE ");
  239. where.append(" tenant_id=? ");
  240. if (StringUtils.isNotBlank(dataId)) {
  241. where.append(" AND data_id=? ");
  242. }
  243. if (StringUtils.isNotBlank(group)) {
  244. where.append(" AND group_id=? ");
  245. }
  246. if (StringUtils.isNotBlank(appName)) {
  247. where.append(" AND app_name=? ");
  248. }
  249. return sql + where + " LIMIT " + pageSize + " OFFSET " + startRow;
  250. }
  251.  
  252. public String findConfigInfoBaseByGroupFetchRows(int startRow, int pageSize) {
  253. return "SELECT id,data_id,group_id,content FROM config_info WHERE group_id=? AND tenant_id=?" + " LIMIT "
  254. + pageSize + " OFFSET " + startRow;
  255. }
  256.  
  257. public String findConfigInfoLike4PageCountRows(Map<String, String> params) {
  258. String dataId = params.get(DATA_ID);
  259. String group = params.get(GROUP);
  260. final String appName = params.get(APP_NAME);
  261. final String content = params.get(CONTENT);
  262. final String sqlCountRows = "SELECT count(*) FROM config_info";
  263. StringBuilder where = new StringBuilder(" WHERE ");
  264. where.append(" tenant_id LIKE ? ");
  265. if (!StringUtils.isBlank(dataId)) {
  266. where.append(" AND data_id LIKE ? ");
  267. }
  268. if (!StringUtils.isBlank(group)) {
  269. where.append(" AND group_id LIKE ? ");
  270. }
  271. if (!StringUtils.isBlank(appName)) {
  272. where.append(" AND app_name = ? ");
  273. }
  274. if (!StringUtils.isBlank(content)) {
  275. where.append(" AND content LIKE ? ");
  276. }
  277. return sqlCountRows + where;
  278. }
  279.  
  280. public String findConfigInfoLike4PageFetchRows(Map<String, String> params, int startRow, int pageSize) {
  281. String dataId = params.get(DATA_ID);
  282. String group = params.get(GROUP);
  283. final String appName = params.get(APP_NAME);
  284. final String content = params.get(CONTENT);
  285. final String sqlFetchRows = "SELECT id,data_id,group_id,tenant_id,app_name,content,encrypted_data_key FROM config_info";
  286. StringBuilder where = new StringBuilder(" WHERE ");
  287. where.append(" tenant_id LIKE ? ");
  288. if (!StringUtils.isBlank(dataId)) {
  289. where.append(" AND data_id LIKE ? ");
  290. }
  291. if (!StringUtils.isBlank(group)) {
  292. where.append(" AND group_id LIKE ? ");
  293. }
  294. if (!StringUtils.isBlank(appName)) {
  295. where.append(" AND app_name = ? ");
  296. }
  297. if (!StringUtils.isBlank(content)) {
  298. where.append(" AND content LIKE ? ");
  299. }
  300. return sqlFetchRows + where + " LIMIT " + pageSize + " OFFSET " + startRow;
  301. }
  302.  
  303. public String findAllConfigInfoFetchRows(int startRow, int pageSize) {
  304. return "SELECT t.id,data_id,group_id,tenant_id,app_name,content,md5 "
  305. + " FROM ( SELECT id FROM config_info WHERE tenant_id LIKE ? ORDER BY id LIMIT " + pageSize
  306. + " OFFSET " + startRow + " )" + " g, config_info t WHERE g.id = t.id ";
  307. }
  308.  
  309. public String findConfigInfosByIds(int idSize) {
  310. StringBuilder sql = new StringBuilder(
  311. "SELECT ID,data_id,group_id,tenant_id,app_name,content,md5 FROM config_info WHERE ");
  312. sql.append("id IN (");
  313. for (int i = 0; i < idSize; i++) {
  314. if (i != 0) {
  315. sql.append(", ");
  316. }
  317. sql.append('?');
  318. }
  319. sql.append(") ");
  320. return sql.toString();
  321. }
  322.  
  323. public String removeConfigInfoByIdsAtomic(int size) {
  324. StringBuilder sql = new StringBuilder("DELETE FROM config_info WHERE ");
  325. sql.append("id IN (");
  326. for (int i = 0; i < size; i++) {
  327. if (i != 0) {
  328. sql.append(", ");
  329. }
  330. sql.append('?');
  331. }
  332. sql.append(") ");
  333. return sql.toString();
  334. }
  335.  
  336. public String updateConfigInfoAtomicCas() {
  337. return "UPDATE config_info SET "
  338. + "content=?, md5 = ?, src_ip=?,src_user=?,gmt_modified=?, app_name=?,c_desc=?,c_use=?,effect=?,type=?,c_schema=? "
  339. + "WHERE data_id=? AND group_id=? AND tenant_id=? AND (md5=? OR md5 IS NULL OR md5='')";
  340. }
  341.  
  342. public String getTableName() {
  343. return TableConstant.CONFIG_INFO;
  344. }
  345.  
  346. }

  3.3.达梦数据源适配实现

   3.3.1.ConfigInfoAggrMapperByDM

  1. package com.alibaba.nacos.plugin.datasource.impl.dm;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
  4. import com.alibaba.nacos.plugin.datasource.impl.common.AbstractConfigInfoAggrMapperCommon;
  5.  
  6. public class ConfigInfoAggrMapperByDM extends AbstractConfigInfoAggrMapperCommon {
  7.  
  8. @Override
  9. public String getDataSource() {
  10. return DataSourceConstant.DM;
  11. }
  12. }
   3.3.2.ConfigInfoBetaMapperByDM

  1. package com.alibaba.nacos.plugin.datasource.impl.dm;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
  4. import com.alibaba.nacos.plugin.datasource.impl.common.AbstractConfigInfoBetaMapperCommon;
  5.  
  6. public class ConfigInfoBetaMapperByDM extends AbstractConfigInfoBetaMapperCommon {
  7.  
  8. @Override
  9. public String getDataSource() {
  10. return DataSourceConstant.DM;
  11. }
  12. }
   3.3.3.ConfigInfoMapperByDM

  1. package com.alibaba.nacos.plugin.datasource.impl.dm;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
  4. import com.alibaba.nacos.plugin.datasource.impl.common.AbstractConfigInfoMapperCommon;
  5.  
  6. public class ConfigInfoMapperByDM extends AbstractConfigInfoMapperCommon {
  7.  
  8. @Override
  9. public String getDataSource() {
  10. return DataSourceConstant.DM;
  11. }
  12. }
   3.3.4.ConfigInfoTagMapperByDM

  1. package com.alibaba.nacos.plugin.datasource.impl.dm;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
  4. import com.alibaba.nacos.plugin.datasource.impl.common.AbstractConfigInfoTagMapperCommon;
  5.  
  6. public class ConfigInfoTagMapperByDM extends AbstractConfigInfoTagMapperCommon {
  7.  
  8. @Override
  9. public String getDataSource() {
  10. return DataSourceConstant.DM;
  11. }
  12. }
   3.3.5.ConfigTagsRelationMapperByDM

  1. package com.alibaba.nacos.plugin.datasource.impl.dm;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
  4. import com.alibaba.nacos.plugin.datasource.impl.common.AbstractConfigTagsRelationMapperCommon;
  5.  
  6. public class ConfigTagsRelationMapperByDM extends AbstractConfigTagsRelationMapperCommon {
  7.  
  8. @Override
  9. public String getDataSource() {
  10. return DataSourceConstant.DM;
  11. }
  12. }
   3.3.6.GroupCapacityMapperByDM

  1. package com.alibaba.nacos.plugin.datasource.impl.dm;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
  4. import com.alibaba.nacos.plugin.datasource.impl.common.AbstractGroupCapacityMapperCommon;
  5.  
  6. public class GroupCapacityMapperByDM extends AbstractGroupCapacityMapperCommon {
  7.  
  8. @Override
  9. public String getDataSource() {
  10. return DataSourceConstant.DM;
  11. }
  12. }
   3.3.7.HistoryConfigInfoMapperByDM

  1. package com.alibaba.nacos.plugin.datasource.impl.dm;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
  4. import com.alibaba.nacos.plugin.datasource.impl.common.AbstractHistoryConfigInfoMapperCommon;
  5.  
  6. public class HistoryConfigInfoMapperByDM extends AbstractHistoryConfigInfoMapperCommon {
  7.  
  8. @Override
  9. public String getDataSource() {
  10. return DataSourceConstant.DM;
  11. }
  12. }
   3.3.8.TenantCapacityMapperByDM

  1. package com.alibaba.nacos.plugin.datasource.impl.dm;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
  4. import com.alibaba.nacos.plugin.datasource.impl.common.AbstractTenantCapacityMapperCommon;
  5.  
  6. public class TenantCapacityMapperByDM extends AbstractTenantCapacityMapperCommon {
  7.  
  8. @Override
  9. public String getDataSource() {
  10. return DataSourceConstant.DM;
  11. }
  12. }
   3.3.9.TenantInfoMapperByDM

  1. package com.alibaba.nacos.plugin.datasource.impl.dm;
  2.  
  3. import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
  4. import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
  5. import com.alibaba.nacos.plugin.datasource.mapper.AbstractMapper;
  6. import com.alibaba.nacos.plugin.datasource.mapper.TenantInfoMapper;
  7.  
  8. public class TenantInfoMapperByDM extends AbstractMapper implements TenantInfoMapper {
  9.  
  10. @Override
  11. public String getTableName() {
  12. return TableConstant.TENANT_INFO;
  13. }
  14.  
  15. @Override
  16. public String getDataSource() {
  17. return DataSourceConstant.DM;
  18. }
  19.  
  20. }

  3.4.其他数据源适配实现

  跟上面达梦数据源适配实现一致,只需将 getDataSource 方法替换成对应的数据源类型就OK;

  3.5.service文件

  在resources下面创建resources/META-INF/services/com.alibaba.nacos.plugin.datasource.mapper.Mapper文件

  1. com.alibaba.nacos.plugin.datasource.impl.dm.ConfigInfoAggrMapperByDM
  2. com.alibaba.nacos.plugin.datasource.impl.dm.ConfigInfoBetaMapperByDM
  3. com.alibaba.nacos.plugin.datasource.impl.dm.ConfigInfoMapperByDM
  4. com.alibaba.nacos.plugin.datasource.impl.dm.ConfigInfoTagMapperByDM
  5. com.alibaba.nacos.plugin.datasource.impl.dm.ConfigTagsRelationMapperByDM
  6. com.alibaba.nacos.plugin.datasource.impl.dm.GroupCapacityMapperByDM
  7. com.alibaba.nacos.plugin.datasource.impl.dm.HistoryConfigInfoMapperByDM
  8. com.alibaba.nacos.plugin.datasource.impl.dm.TenantCapacityMapperByDM
  9. com.alibaba.nacos.plugin.datasource.impl.dm.TenantInfoMapperByDM
  10.  
  11. #其他类似..............

  3.6.nacos-server配置

  1)mvn install后该jar包放入到Nacos(版本2.2.0才支持数据源插件化)的plugins目录下(没有则新建),Nacos的启动脚本startup.sh中-Dloader.path参数将会加载外部jar包文件到Nacos的环境中;

  2)修改Nacos的conf/application.properties,增加对应数据源的连接参数信息:

  1. db.num=1
  2. #指定数据源类型,对应DataSourceConstant参数
  3. spring.sql.init.platform=dm
  4. db.url.0=jdbc:dm://ip:5236/
  5. db.user.0=username
  6. db.password.0=password
  7. #指定driver
  8. db.pool.config.driverClassName=dm.jdbc.driver.DmDriver

  3.7.启动

  1)启动命令:

   单机模式:sudo sh startup.sh -m standalone

  集群模式:./startup.sh

  PS:

  集群模式下修改cluster.conf.example文件为cluster.conf,不然报错误: Caused by: com.alibaba.nacos.api.exception.NacosException: java.net.UnknownHostException: jmenv.tbsite.net

  2)ip访问验证:http://ip:8848/nacos/index.html

二.源码探究

  1.准备

  源码nacos-2.2.0:https://github.com/alibaba/nacos.git

  2.网页入口

  nacos-console模块com.alibaba.nacos.Nacos

  3.nacos数据持久化入口

   3.1.com.alibaba.nacos.config.server.service.repository.extrnal.ExternalStoragePersistServiceImpl#init()

  1. @PostConstruct
  2. public void init() {
  3. //获取数据源
  4. dataSourceService = DynamicDataSource.getInstance().getDataSource();
  5.  
  6. jt = getJdbcTemplate();
  7. tjt = getTransactionTemplate();
  8. Boolean isDataSourceLogEnable = EnvUtil
  9. .getProperty(Constants.NACOS_PLUGIN_DATASOURCE_LOG, Boolean.class, false);
  10. mapperManager = MapperManager.instance(isDataSourceLogEnable);
  11. }
  12.  
  13. com.alibaba.nacos.config.server.service.datasource.DynamicDataSource#getDataSource
  14. public synchronized DataSourceService getDataSource() {
  15. try {
  16.  
  17. // Embedded storage is used by default in stand-alone mode
  18. // In cluster mode, external databases are used by default
  19. //单机模式
  20. if (PropertyUtil.isEmbeddedStorage()) {
  21. if (localDataSourceService == null) {
  22. localDataSourceService = new LocalDataSourceServiceImpl();
  23. localDataSourceService.init();
  24. }
  25. return localDataSourceService;
  26. } else {
  27. //集群模式
  28. if (basicDataSourceService == null) {
  29. basicDataSourceService = new ExternalDataSourceServiceImpl();
  30. basicDataSourceService.init();
  31. }
  32. return basicDataSourceService;
  33. }
  34. } catch (Exception e) {
  35. throw new RuntimeException(e);
  36. }
  37. }

   3.2.com.alibaba.nacos.config.server.service.datasource.ExternalDataSourceServiceImpl#init

  1. @Override
  2. public void init() {
  3. queryTimeout = ConvertUtils.toInt(System.getProperty("QUERYTIMEOUT"), 3);
  4. jt = new JdbcTemplate();
  5. // Set the maximum number of records to prevent memory expansion
  6. jt.setMaxRows(50000);
  7. jt.setQueryTimeout(queryTimeout);
  8.  
  9. testMasterJT = new JdbcTemplate();
  10. testMasterJT.setQueryTimeout(queryTimeout);
  11.  
  12. testMasterWritableJT = new JdbcTemplate();
  13. // Prevent the login interface from being too long because the main library is not available
  14. testMasterWritableJT.setQueryTimeout(1);
  15.  
  16. // Database health check
  17.  
  18. testJtList = new ArrayList<>();
  19. isHealthList = new ArrayList<>();
  20.  
  21. tm = new DataSourceTransactionManager();
  22. tjt = new TransactionTemplate(tm);
  23.  
  24. // Transaction timeout needs to be distinguished from ordinary operations.
  25. tjt.setTimeout(TRANSACTION_QUERY_TIMEOUT);
  26. //获取数据源类型:spring.sql.init.platform或spring.datasource.platform指定的参数值
  27. dataSourceType = DatasourcePlatformUtil.getDatasourcePlatform(defaultDataSourceType);
  28.  
  29. if (PropertyUtil.isUseExternalDB()) {
  30. try {
  31. //加载数据源连接
  32. reload();
  33. } catch (IOException e) {
  34. FATAL_LOG.error("[ExternalDataSourceService] datasource reload error", e);
  35. throw new RuntimeException(DB_LOAD_ERROR_MSG, e);
  36. }
  37.  
  38. if (this.dataSourceList.size() > DB_MASTER_SELECT_THRESHOLD) {
  39. ConfigExecutor.scheduleConfigTask(new SelectMasterTask(), 10, 10, TimeUnit.SECONDS);
  40. }
  41. ConfigExecutor.scheduleConfigTask(new CheckDbHealthTask(), 10, 10, TimeUnit.SECONDS);
  42. }
  43. }

   3.3.com.alibaba.nacos.config.server.service.datasource.ExternalDataSourceServiceImpl#reload

  1. @Override
  2. public synchronized void reload() throws IOException {
  3. try {
  4. final List<JdbcTemplate> testJtListNew = new ArrayList<JdbcTemplate>();
  5. final List<Boolean> isHealthListNew = new ArrayList<Boolean>();
  6. //com.alibaba.nacos.config.server.service.datasource.ExternalDataSourceProperties#build:获取数据源
  7. List<HikariDataSource> dataSourceListNew = new ExternalDataSourceProperties()
  8. .build(EnvUtil.getEnvironment(), (dataSource) -> {
  9. JdbcTemplate jdbcTemplate = new JdbcTemplate();
  10. jdbcTemplate.setQueryTimeout(queryTimeout);
  11. jdbcTemplate.setDataSource(dataSource);
  12. testJtListNew.add(jdbcTemplate);
  13. isHealthListNew.add(Boolean.TRUE);
  14. });
  15. final List<HikariDataSource> dataSourceListOld = dataSourceList;
  16. final List<JdbcTemplate> testJtListOld = testJtList;
  17. dataSourceList = dataSourceListNew;
  18. testJtList = testJtListNew;
  19. isHealthList = isHealthListNew;
  20. //选择主数据源:测试数据源,数据源设置到JdbcTemplate jt中(重点,后续请求从jt中获取dataSource)
  21. new SelectMasterTask().run();
  22. //校验数据源的状态
  23. new CheckDbHealthTask().run();
  24.  
  25. //close old datasource.
  26. if (dataSourceListOld != null && !dataSourceListOld.isEmpty()) {
  27. for (HikariDataSource dataSource : dataSourceListOld) {
  28. dataSource.close();
  29. }
  30. }
  31. if (testJtListOld != null && !testJtListOld.isEmpty()) {
  32. for (JdbcTemplate oldJdbc : testJtListOld) {
  33. oldJdbc.setDataSource(null);
  34. }
  35. }
  36. } catch (RuntimeException e) {
  37. FATAL_LOG.error(DB_LOAD_ERROR_MSG, e);
  38. throw new IOException(e);
  39. }
  40. }

   3.4.com.alibaba.nacos.config.server.service.datasource.ExternalDataSourceProperties#build:根据application.properties配置连接获取数据源

  1. List<HikariDataSource> build(Environment environment, Callback<HikariDataSource> callback) {
  2. List<HikariDataSource> dataSources = new ArrayList<>();
  3. Binder.get(environment).bind("db", Bindable.ofInstance(this));
  4. Preconditions.checkArgument(Objects.nonNull(num), "db.num is null");
  5. Preconditions.checkArgument(CollectionUtils.isNotEmpty(user), "db.user or db.user.[index] is null");
  6. Preconditions.checkArgument(CollectionUtils.isNotEmpty(password), "db.password or db.password.[index] is null");
  7. for (int index = 0; index < num; index++) {
  8. int currentSize = index + 1;
  9. Preconditions.checkArgument(url.size() >= currentSize, "db.url.%s is null", index);
  10. //获取driverClassName
  11. DataSourcePoolProperties poolProperties = DataSourcePoolProperties.build(environment);
  12. if (StringUtils.isEmpty(poolProperties.getDataSource().getDriverClassName())) {
  13. poolProperties.setDriverClassName(JDBC_DRIVER_NAME);
  14. }
  15. poolProperties.setJdbcUrl(url.get(index).trim());
  16. poolProperties.setUsername(getOrDefault(user, index, user.get(0)).trim());
  17. poolProperties.setPassword(getOrDefault(password, index, password.get(0)).trim());
  18. HikariDataSource ds = poolProperties.getDataSource();
  19. if (StringUtils.isEmpty(ds.getConnectionTestQuery())) {
  20. ds.setConnectionTestQuery(TEST_QUERY);
  21. }
  22. dataSources.add(ds);
  23. callback.accept(ds);
  24. }
  25. Preconditions.checkArgument(CollectionUtils.isNotEmpty(dataSources), "no datasource available");
  26. return dataSources;
  27. }

   3.5.com.alibaba.nacos.config.server.service.datasource.DataSourcePoolProperties#build

  1. public static DataSourcePoolProperties build(Environment environment) {
  2. DataSourcePoolProperties result = new DataSourcePoolProperties();
  3. //绑定driverClassName值
  4. Binder.get(environment).bind("db.pool.config", Bindable.ofInstance(result.getDataSource()));
  5. return result;
  6. }

   3.6.com.alibaba.nacos.plugin.datasource.MapperManager#loadInitial:nacos-datasource-plugin

  1. public void loadInitial() {
  2. //spi加载插件实现类
  3. Collection<Mapper> mappers = NacosServiceLoader.load(Mapper.class);
  4. for (Mapper mapper : mappers) {
  5. Map<String, Mapper> mapperMap = MAPPER_SPI_MAP.getOrDefault(mapper.getDataSource(), new HashMap<>(16));
  6. mapperMap.put(mapper.getTableName(), mapper);
  7. MAPPER_SPI_MAP.put(mapper.getDataSource(), mapperMap);
  8. LOGGER.info("[MapperManager] Load Mapper({}) datasource({}) tableName({}) successfully.",
  9. mapper.getClass(), mapper.getDataSource(), mapper.getTableName());
  10. }
  11. }

  ps:

  SPI:Service Provider Interface (服务提供接口) 是java提供的一套用来被第三方实现或扩展的接口。它可以用来启用框架 扩展和替换 组件;

  SPI 与API 区别与联系

    API: (Application Programming Interface) 在绝大多数情况下,都是实现方定制接口并进行接口的实现,调用者只能选择调用,而无权选择不同实现;

    SPI: 调用方制定接口规范,提供给外部实现。调用方在调用时选择自己需要的外部实现;

  流程:

  1)定义一个接口,定义接口的实现类;

  2)在resources目录下新建META-INF/services目录,并且在这个目录下新建一个与上述接口的全限定名一致的文件,在这个文件中写入接口的实现类的全限定名;

  3)通过serviceLoader加载实现类并调用

  1. public static void main(String[] args) {
  2. ServiceLoader<Mapper> mappers = ServiceLoader.load(Mapper.class);
  3. for (Mapper m : mappers) {
  4. m.getTableName();
  5. }
  6. }

  pps:在 ServiceLoader.load 后遍历 mappers 时可以通过 BeanDefinitionRegistry 可以将mapper实现类注册到 ApplicationContext中,这样就可以对接口实现类使用 @Autowired 来解决依赖注入问题了;

   3.7.com.alibaba.nacos.config.server.service.dump.ExternalDumpService#init:将数据库的config_info信息dump一份到本地磁盘

  1. @PostConstruct
  2. @Override
  3. protected void init() throws Throwable {
  4. dumpOperate(processor, dumpAllProcessor, dumpAllBetaProcessor, dumpAllTagProcessor);
  5. }

  ps:

  有兴趣可研究 ExternalDumpService#init -> DumpService#dumpConfigInfo -> DumpAllProcessor#process(第一行定位到3.8) -> ExternalStoragePersistServiceImpl#findAllConfigInfoFragment -> 分页将数据库的config_info(nacos的配置管理的配置列表信息)dump到本地磁盘 -> ConfigCacheService#dump -> DiskUtil#saveToDisk

  pps:所以nacos的配置信息优先从本地取,本地为空再从数据库取并更新到本地;

  可从 ConfigController#getConfig -> ConfigServletInner#doGetConfig() 中看到从本地缓存取,失败再从数据库查询并更新到本地;

   3.8.com.alibaba.nacos.config.server.service.repository.extrnal.ExternalConfigInfoPersistServiceImpl#findConfigMaxId

  1. public long findConfigMaxId() {
  2. //获取config_info表实现类
  3. ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(),
  4. TableConstant.CONFIG_INFO);
  5. String sql = configInfoMapper.findConfigMaxId();
  6. try {
  7. return jt.queryForObject(sql, Long.class);
  8. } catch (NullPointerException e) {
  9. return 0;
  10. }
  11. }

   3.9.com.alibaba.nacos.plugin.datasource.MapperManager#findMapper

  1. public <R extends Mapper> R findMapper(String dataSource, String tableName) {
  2. LOGGER.info("[MapperManager] findMapper dataSource: {}, tableName: {}", dataSource, tableName);
  3. if (StringUtils.isBlank(dataSource) || StringUtils.isBlank(tableName)) {
  4. throw new NacosRuntimeException(FIND_DATASOURCE_ERROR_CODE, "dataSource or tableName is null");
  5. }
  6. Map<String, Mapper> tableMapper = MAPPER_SPI_MAP.get(dataSource);
  7. if (Objects.isNull(tableMapper)) {
  8. throw new NacosRuntimeException(FIND_DATASOURCE_ERROR_CODE,
  9. "[MapperManager] Failed to find the datasource,dataSource:" + dataSource);
  10. }
  11. Mapper mapper = tableMapper.get(tableName);
  12. if (Objects.isNull(mapper)) {
  13. throw new NacosRuntimeException(FIND_TABLE_ERROR_CODE,
  14. "[MapperManager] Failed to find the table ,tableName:" + tableName);
  15. }
  16. //nacos.plugin.datasource.log.enabled=true开启日志:jdk代理
  17. if (dataSourceLogEnable) {
  18. MapperProxy mapperProxy = new MapperProxy();
  19. return (R) mapperProxy.createProxy(mapper);
  20. }
  21. return (R) mapper;
  22. }

nacos适配达梦、瀚高、人大金仓数据库及部分源码探究的更多相关文章

  1. 通过ODBC接口访问人大金仓数据库

      国产化软件和国产化芯片的窘境一样,一方面市场已经存在性能优越的同类软件,成本很低,但小众的国产化软件不仅需要高价买入版权,并且软件开发维护成本高:另一方面,国产软件目前普遍难用,性能不稳定,Bug ...

  2. QT 之 ODBC连接人大金仓数据库

    QT 之 使用 ODBC 驱动连接人大金仓数据库 获取数据库驱动和依赖动态库 此操作可在人大金仓官网下载与系统匹配的接口动态库,或者从架构数据库的源码中获取驱动和依赖动态库 分别为: 驱动动态库:kd ...

  3. 通过jmeter连接人大金仓数据库

    某项目用的人大金仓数据库,做性能测试,需要用jmeter来连接数据库处理一批数据.jmeter连接人大金仓,做个记录. 1. 概要 在"配置元件"中添加"JDBC Con ...

  4. DBeaver连接达梦|虚谷|人大金仓等国产数据库

    前言 工作中有些项目可能会接触到「达梦.虚谷.人大金仓」等国产数据库,但通常这些数据库自带的连接工具使用并不方便,所以这篇文章记录一下 DBeaver 连接国产数据库的通用模版,下文以达梦为例(其他国 ...

  5. 教你10分钟对接人大金仓EF Core 6.x

    前言 目前.NET Core中据我了解到除了官方的EF Core外,还用的比较多的ORM框架(恕我孤陋寡闻哈,可能还有别的)有FreeSql.SqlSugar(排名不分先后).FreeSql和SqlS ...

  6. 高仿精仿开心网应用android源码

    今天早上看到了一个不错的安卓应用源码项目,真的非常不错高仿精仿开心网应用android源码下载,希望大家能够喜欢.       原文:http://android.662p.com/thread-29 ...

  7. 高仿精仿快播应用android源码下载

    今天给大家在网上找到的一款高仿精仿快播应用android源码,分享给大家,希望大家功能喜欢. 说明源码更新中.... 源码即将上传 也可以到这个网站下载:download

  8. VopSdk一个高逼格微信公众号开发SDK(源码下载)

    看之前回复很多说明大家很有热情&文章被误删掉了,不想让有的朋友错失这个高逼格的东西,现在重新发布,这次就直接放出源码,文章最末下载地址. 看之前回复很多说明大家很有热情&文章被误删掉了 ...

  9. 高仿ios版美团框架项目源码

    高仿美团框架基本已搭好.代码简单易懂,适合新人.适合新人.新人. <ignore_js_op>     源码你可以到ios教程网那里下载吧,这里我就不上传了,http://ios.662p ...

  10. 高仿一元云购IOS应用源码项目

    高仿一元云购IOS应用(高仿自一元云购安卓客户端) 本App因官方没有IOS客户端故开发,利用业务时间历时2个星期,终于开发完成,又因苹果的各大审核规则对此App的影响,又历时1个多月才终于成功上架, ...

随机推荐

  1. 使用vue-cli创建第一个vue项目

    命令提示符切换至需要创建项目的目录: 直接在路径输入cmd在按键盘的enter键打开的终端就直接切换到该目录下 (1)输入以下命令: vue create 项目名称 (2)我这里选手动选择,键盘上下按 ...

  2. Django 如何使用 Celery 完成异步任务或定时任务

    以前版本的 Celery 需要一个单独的库(django-celery)才能与 Django 一起工作, 但从 Celery 3.1 开始,情况便不再如此,我们可以直接通过 Celery 库来完成在 ...

  3. win系统安装wordcloud报错解决方案

    问题: ① 在命令行下执行pip install wordcloud出现报错如图: ②下载了错误的whl文件, 出现wordcloud-1.4.1-cp27-cp27m-win_amd64.whl i ...

  4. rfc7234之http缓存

    声明:本人原创文章,详细内容已发布在我的微信个人技术公众号---网络技术修炼,公众号总结普及网络基础知识,包括基础原理.网络方案.开发经验和问题定位案例等,欢迎关注. 缓存概念 缓存处理请求步骤 缓存 ...

  5. SPN在域环境的应用

    windows域为了集中资源,有效地对资源访问控制权限进行细粒度分配,提高网络资源统一分配的管理.域内的每种资源分配了不同的服务主体名称(SERVICE Pricipal Name,SPN) 相关概念 ...

  6. 如何实现一个sync.Once

    sync.Once 是 golang里用来实现单例的同步原语.Once 常常用来初始化单例资源, 或者并发访问只需初始化一次的共享资源,或者在测试的时候初始化一次测试资源. 单例,就是某个资源或者对象 ...

  7. 2022-12-27:etcd是无界面的,不好看,joinsunsoft/etcdv3-browser是etcd的web可视化工具之一。请问在k3s中部署,yaml如何写?

    2022-12-27:etcd是无界面的,不好看,joinsunsoft/etcdv3-browser是etcd的web可视化工具之一.请问在k3s中部署,yaml如何写? 答案2022-12-27: ...

  8. 这款全自动自适应工具你用过了吗?autofit.js请求加入你的战场!

    前段时间做了一个自适应的小工具(autofit.js) 经过一段时间的试用,同学们发现了工具存在的一些问题,我自己也发现了一些,这篇文章是针对这些问题撰写的. autofit.js autofit.j ...

  9. Python从零到壹丨图像增强的顶帽运算和底帽运算

    摘要:这篇文章详细介绍了顶帽运算和底帽运算,它们将为后续的图像分割和图像识别提供有效支撑. 本文分享自华为云社区<[Python从零到壹] 四十九.图像增强及运算篇之顶帽运算和底帽运算>, ...

  10. this关键字理解

    编译器对对象的加载步骤: (1)类名 (2)成员变量 (3)成员方法 即使定义类时,成员变量写在成员方法后面,加载对象时,也是先加载成员变量 当编译器识别方法时,会对成员方法改写,在所有方法里隐藏一个 ...