当前位置: 首页 > news >正文

ShardingSphereJDBC5.4.0支持Nacos配置(SpringCloud版)

背景

在ShardingSphere在5.3.0版本之前,我们可以通过依赖shardingsphere-jdbc-core-spring-boot-starter模块,在application.yml文件里配置数据库连接信息。再结合spring-cloud-starter-alibaba-nacos-config,在项目启动时,从Nacos后台动态的拉取数据库配置,实现了配置文件和代码分离,避免了改配置需要重新打包。在5.3.0之后(包含),ShardingSphere由于兼容各个spring版本造成工作量巨大,而放弃了对spring的支持,提供了另一种方式ShardingSphere Driver来连接数据库( issue-22469)。但使用ShardingSphere Driver后,也就无法通过spring-cloud-starter-alibaba-nacos-config自动载入数据库配置。

ShardingSphere Driver为什么无法支持Nacos

ShardingSphere Driver的核心是自己提供了ShardingSphereDriver,从而支持这种格式的JDBC URL:jdbc:shardingsphere:${path}/config.yaml。我们可以把ShardingSphere的规则写到config.yaml文件里,然后通过ShardingSphereDriverURLProvider(5.4.1后改名ShardingSphereURLProvider)接口来支持不同的${path}的文件寻址方式。默认支持

absolutepath(服务器绝对路径)、classpath、apollo(5.4.1把功能挪到了ShardingSphere plugin仓库里)。所以在官方实现里,并不支持通过Nacos获取config.yaml信息。需要在Spring Boot项目里支持Nacos,就要自定义Nacos的ShardingSphereURLProvider。

Nacos的ShardingJdbcURLProvider

ShardingSphereDriverURLProvider是通过SPI的方式实现扩展,我们在自定义ShardingJdbcNacosURLProvider后,要把ShardingJdbcNacosURLProvider类信息放到META-INF/services/org.apache.shardingsphere.driver.jdbc.core.driver.ShardingSphereDriverURLProvider文件里,这样就被ShardingSphere找到。自定义支持Nacos的ShardingSphereURLProvider 大概长这样:

public final class ShardingJdbcNacosURLProvider implements ShardingSphereDriverURLProvider {

    private static final String CLASSPATH_TYPE = "nacos:";

    private static final String URL_PREFIX = "jdbc:shardingsphere:";

    @Override

    public boolean accept(final String url) {

        return !Strings.isNullOrEmpty(url) && url.contains(CLASSPATH_TYPE);

    }

    @SneakyThrows

    @Override

    public byte[] getContent(String url) {

        String configPath = url.substring(URL_PREFIX.length(), url.contains("?") ? url.indexOf('?') : url.length());

        String dataId = configPath.substring(CLASSPATH_TYPE.length());

        NacosConfigProperties nacosConfigProperties = NacosConfigiServiceUtils.getConfigManager().getNacosConfigProperties();

        String content = NacosConfigiServiceUtils.getConfigService().getConfig(dataId, nacosConfigProperties.getGroup(), nacosConfigProperties.getTimeout());

        return content.getBytes(StandardCharsets.UTF_8);

    }

}

与Spring Boot结合

要用Nacos拉取配置,就要访问Nacos管理API,spring-cloud-starter-alibaba-nacos-config里是通过NacosConfigManager对象来访问Nacos数据。具体方式是NacosConfigManager对象里有一个ConfigService对象,最终通过ConfigService的getConfig(String dataId, String group, long timeoutMs)方式获取配置信息。

如何在ShardingSphereDriverURLProvider里访问NacosConfigManager对象?

ShardingSphereDriverURLProvider是通过SPI方式加载,所以无法直接注入Spring的BeanFactory,只能通过静态方法的方式获取NacosConfigManager对象,那么就需要我们提前把NacosConfigManager对象准备好。上面的代码里,我把NacosConfigManager对象放到了NacosConfigiServiceUtils工具类里。

public class NacosConfigiServiceUtils {

    private static NacosConfigManager configManager;

    private static ConfigService configService;

    public static void init(NacosConfigManager nacosConfigManager) {

        configManager = nacosConfigManager;

        configService = nacosConfigManager.getConfigService();

    }

    public static NacosConfigManager getConfigManager() {

        return configManager;

    }

    public static ConfigService getConfigService() {

        return configService;

    }

}

怎么保证访问NacosConfigiServiceUtils的时候,NacosConfigManager对象已经Ready?

ShardingSphereDriverURLProvider的getContent()方法是在第一次访问ShardingSphereDriver.connect()方法的时候被调用,在connect()方法里会先创建出DataSource,这就需要数据库配置信息。所以,需要在访问connect()方法之前就准备好NacosConfigManager对象。

NacosConfigManager的创建时机

NacosConfigManager对象是在com.alibaba.cloud.nacos.NacosConfigBootstrapConfiguration配置类里初始化。NacosConfigBootstrapConfiguration配置类是Spring Cloud通过org.springframework.cloud.bootstrap.BootstrapConfiguration=com.alibaba.cloud.nacos.NacosConfigBootstrapConfiguration方式加载。BootstrapConfiguration加载的Bean是在Spring Cloud容器(Spring Boot的父容器)里,所以天然比ShardingSphereDriver(在Spring Boot容器)初始化时机要早。所以加载完NacosConfigBootstrapConfiguration之后,我们有机会把NacosConfigManager对象放到NacosConfigiServiceUtils里。

获取NacosConfigManager对象

有两种方式拿到NacosConfigManager对象。

  1. 自定一个BootstrapConfiguration配置类,然后注入NacosConfigManager对象,再把NacosConfigManager对象放入NacosConfigiServiceUtils。
  2. 注册一个ApplicationListerner,监听ContextRefreshedEvent,Spring Cloud容器在初始化完之后会发送ContextRefreshedEvent事件,这时也能通过ApplicationContext对象拿到NacosConfigManager对象。

方式一的示例代码如下:

@ConditionalOnClass(name = "com.alibaba.cloud.nacos.NacosConfigBootstrapConfiguration")

public class NacosUtilsBootstrapConfiguration {

    public NacosUtilsBootstrapConfiguration(NacosConfigManager nacosConfigManager) {

        NacosConfigiServiceUtils.init(nacosConfigManager);

    }

}

然后把org.springframework.cloud.bootstrap.BootstrapConfiguration=com.common.core.NacosUtilsBootstrapConfiguration放入META-INF/spring.factories文件,这样NacosUtilsBootstrapConfiguration就能生效了。

小结

至此,我们就实现了通过ShardingSphereDriverURLProvider访问Nacos拿到数据库配置。在修改数据库配置后,也只需要重启服务就能拿到最新的配置。ShardingSphere在放弃Spring后,框架的初始化流程上就比较难和Spring结合。本文通过自定义BootstrapConfiguration实现了Nacos和ShardingSphere的结合,尽量通过框架的扩展功能来实现功能逻辑。

http://www.lryc.cn/news/185060.html

相关文章:

  • 基于SSM的学院学生论坛系统的设计与实现
  • Unity记录5.4-地图-带种子的柏林噪声
  • 阅读论文:Label-Free Liver Tumor Segmentation
  • leetcode64 最小路径和
  • 金盘图书馆微信管理后台信息泄露漏洞 复现
  • nginx实现负载均衡(三)
  • Android---深入理解ClassLoader的加载机制
  • 超自动化加速落地,助力运营效率和用户体验显著提升|爱分析报告
  • Linux posix_spawn和fork的区别
  • 聊聊分布式架构02——Http到Https
  • 1024 画跳动的爱心#程序代码 #编程语言 #计算机
  • 【排序算法】堆排序详解与实现
  • java Spring Boot整合jwt实现token生成
  • 如何使用Git和GitHub进行版本控制
  • 彻底解决 WordPress cURL error 28 错误
  • LLM项目代码改写
  • 小谈设计模式(14)—建造者模式
  • 【kubernetes】k8s中的选主机制
  • 学生选课系统基础版
  • redis no-appendfsync-on-rewrite
  • Spring Cloud Gateway2之路由详解
  • 阿里云RDS关系型数据库详细介绍_多版本数据库说明
  • Vue中的数据绑定
  • 前后端分离计算机毕设项目之基于SpringBoot的旅游网站的设计与实现《内含源码+文档+部署教程》
  • [JAVAee]Spring拦截器
  • 【nvm】Node Version Manager(NVM)安装配置以及使用(WIN版)
  • 【微服务】七. http客户端Feign
  • 【Spring Boot 源码学习】OnWebApplicationCondition 详解
  • 力扣之二分法
  • css图形化理解--扭曲函数skew()