当前位置: 首页 > 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的结合,尽量通过框架的扩展功能来实现功能逻辑。

相关文章:

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

背景 在ShardingSphere在5.3.0版本之前,我们可以通过依赖shardingsphere-jdbc-core-spring-boot-starter模块,在application.yml文件里配置数据库连接信息。再结合spring-cloud-starter-alibaba-nacos-config,在项目启动时,从Nac…...

基于SSM的学院学生论坛系统的设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用Vue技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...

Unity记录5.4-地图-带种子的柏林噪声

文章首发见博客:https://mwhls.top/4850.html。 无图/格式错误/后续更新请见首发页。 更多更新请到mwhls.top查看 欢迎留言提问或批评建议,私信不回。 汇总:Unity 记录 现在卡在了跨地图洞穴生成,没想到什么好的方法能够像地面一样…...

阅读论文:Label-Free Liver Tumor Segmentation

论文标题:Label-Free Liver Tumor Segmentation 翻译:无标记的肝肿瘤分割 摘要 论文的目的:肿瘤合成,通过使用合成数据来改进医学图像分析和AI在肝脏肿瘤检测方面的性能 我们的主要贡献是合成了一种肿瘤生成器,它提…...

leetcode64 最小路径和

题目 给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 说明:每次只能向下或者向右移动一步。 示例 输入:grid [[1,3,1],[1,5,1],[4,2,1]] 输出:7 解释&a…...

金盘图书馆微信管理后台信息泄露漏洞 复现

金盘图书馆微信管理后台信息泄露漏洞 复现 0x01 前言 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果…...

nginx实现负载均衡(三)

之前说过大部分我们用到的配置都是在http模块中配置的,这里要实现的负载均衡也是一样的,要在http模块中的http全局块中指定,这里我们先给出一个例子 demo #user nobody; worker_processes 1;#error_log logs/error.log; #error_log log…...

Android---深入理解ClassLoader的加载机制

目录 Java 中的 ClassLoader 1. APPClassLoader 系统类加载器 2. ExtClassLoader 扩展类加载器 3. BootstrapClassLoader 启动类加载器 双亲委派模式(Parents Delegation Model) Android 中的 ClassLoader 1. PathClassLoader 2. DexClassLoader 总结 一个完整的 Java…...

超自动化加速落地,助力运营效率和用户体验显著提升|爱分析报告

RPA、iPaaS、AI、低代码、BPM、流程挖掘等在帮助企业实现自动化的同时,也在构建一座座“自动化烟囱”。自动化工具尚未融为一体,协同价值没有得到释放。Gartner于2019年提出超自动化(Hyperautomation)概念,主要从技术组…...

Linux posix_spawn和fork的区别

posix_spawn和fork都是用于在Linux中创建新进程的函数,但它们的工作方式有所不同。posix_spawn它的工作方式类似于fork()后跟exec()。 fork:fork函数创建一个新的进程,该进程是调用进程的一个副本。这意味着除了必要的启动资源外,…...

聊聊分布式架构02——Http到Https

目录 HTTP通信协议 请求报文 响应报文 持久连接 状态管理 HTTPS通信协议 安全的HTTPS HTTP到HTTPS的演变 对称加密 非对称加密 混合加密机制 证书机构 SSL到底是什么 HTTPS是身披SSL外壳的HTTP HTTP通信协议 一次HTTP请求的通信流程:客户端浏览器通过…...

1024 画跳动的爱心#程序代码 #编程语言 #计算机

废话不多说 直接开干! 用到库 random time tkinter 快速镜像 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tkinter 上代码 import random import time from math import sin, cos, pi, log from tkinter import *CANVAS_WIDTH 640 # 画布的宽 CANVAS_HEIGH…...

【排序算法】堆排序详解与实现

一、堆排序的思想 堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆(若不清楚什么是堆,可以看我前面的文章,有详细阐述)来进行选择数据&am…...

java Spring Boot整合jwt实现token生成

先在 pom.xml 文件中注入依赖 <!-- JWT --> <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.2</version> </dependency> <dependency><groupId>io.jsonw…...

如何使用Git和GitHub进行版本控制

如何使用Git和GitHub进行版本控制 版本控制是软件开发过程中的重要组成部分&#xff0c;它允许开发者跟踪和管理代码的变化&#xff0c;以确保团队协作顺畅&#xff0c;并帮助在需要时回溯到以前的代码状态。Git和GitHub是最流行的版本控制工具之一&#xff0c;本文将介绍如何…...

彻底解决 WordPress cURL error 28 错误

cURL 连接超时。 这种情况最普遍&#xff0c;这里的超时并不是完全不可连接&#xff0c;而是因为网络状况或其它原因数据传输缓慢&#xff0c;超过连接的时间限制导致传输中断引起的错误。 不论是何种原因导致连接超时&#xff0c;都可以通过增加超时限制来解决此问题。但 UR…...

LLM项目代码改写

背景&#xff1a; 最近在做代码大语言模型生成项目代码的课题。代码生成现在大部分的工作是在做即时代码生成&#xff0c;这个有点类似代码智能提示&#xff0c;只不过生成的可能是一段片段代码&#xff1b;然而对于整个项目代码的生成做的团队并不多&#xff0c;原因大致如下…...

小谈设计模式(14)—建造者模式

小谈设计模式&#xff08;14&#xff09;—建造者模式 专栏介绍专栏地址专栏介绍 建造者模式角色分类产品&#xff08;Product&#xff09;抽象建造者&#xff08;Builder&#xff09;具体建造者&#xff08;Concrete Builder&#xff09;指挥者&#xff08;Director&#xff0…...

【kubernetes】k8s中的选主机制

leader-election选主机制 1 为什么需要leader-election&#xff1f; 在集群中存在某种业务场景&#xff0c;一批相同功能的进程同时运行&#xff0c;但是同一时刻&#xff0c;只能有一个工作&#xff0c;只有当正在工作的进程异常时&#xff0c;才会由另一个进程进行接管。这…...

学生选课系统基础版

第四章java中的集合框架 4.1&#xff1a;java中的集合框架概述 1.java概念与作用 现实中很多事物凑在一起都是集合 如购物车是商品的集合 军队呢 是军人的集合 学校是学生的结合 数学中的集合&#xff1a; 具有共同属性的事物的总体 java中的集合类呢 跟数学的集…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

C++_哈希表

本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、基础概念 1. 哈希核心思想&#xff1a; 哈希函数的作用&#xff1a;通过此函数建立一个Key与存储位置之间的映射关系。理想目标&#xff1a;实现…...

第八部分:阶段项目 6:构建 React 前端应用

现在&#xff0c;是时候将你学到的 React 基础知识付诸实践&#xff0c;构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段&#xff0c;你可以先使用模拟数据&#xff0c;或者如果你的后端 API&#xff08;阶段项目 5&#xff09;已经搭建好&#xff0c;可以直接连…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

Python学习(8) ----- Python的类与对象

Python 中的类&#xff08;Class&#xff09;与对象&#xff08;Object&#xff09;是面向对象编程&#xff08;OOP&#xff09;的核心。我们可以通过“类是模板&#xff0c;对象是实例”来理解它们的关系。 &#x1f9f1; 一句话理解&#xff1a; 类就像“图纸”&#xff0c;对…...