三步实现 Sentinel-Nacos 持久化

一、背景

版本:【Sentinel-1.8.6】
模式:【Push 模式】

参照官网介绍:生产环境下使用Sentinel ,规则管理及推送模式有以下3种模式:在这里插入图片描述
比较之后,目前微服务都使用了各种各样的配置中心,故采用Push 模式来进行持久化,这里也主要介绍集合 Nacos 的持久化。

二、流程结构图

在这里插入图片描述
实现思路说明:微服务中增加基于Nacos的写数据源(WritableDataSource),当 Sentinel Dashboard 配置发生变更,则利用 nacos 配置变更通知微服务更新本地缓存。

三、代码整合

1. 在微服务中引入依赖。
 <!--sentinel持久化 采用 Nacos 作为规则配置数据源-->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
依赖缘由

(ps: 至于为何要引入这个依赖,在此做下展开说明,着急的同学请略过看)
可以看到这个依赖包的源码中只有一个类,那么这个类一定很重要了,看看它具体做了啥:
在这里插入图片描述
NacosDataSource 中构造方法如下,里面有个重要的东西: configListener,我们先记住红框框起来的地方。
在这里插入图片描述
看看具体的方法 initNacosListener();loadInitialConfig();

// 初始化 Nacos 监听器
private void initNacosListener() {try {// 根据数据源配置信息初始化Nacos 的配置服务: configService this.configService = NacosFactory.createConfigService(this.properties);// 添加配置监听器.configService.addListener(dataId, groupId, configListener);} catch (Exception e) {RecordLog.warn("[NacosDataSource] Error occurred when initializing Nacos data source", e);e.printStackTrace();}
}// 加载Nacos 已有配置文件
private void loadInitialConfig() {try {T newValue = loadConfig();if (newValue == null) {RecordLog.warn("[NacosDataSource] WARN: initial config is null, you may have to check your data source");}getProperty().updateValue(newValue);} catch (Exception ex) {RecordLog.warn("[NacosDataSource] Error when loading initial config", ex);}
}

又由于 NacosDataSource 继承自 AbstractDataSource,故此处的 loadConfig() 方法是调用 com.alibaba.csp.sentinel.datasource.AbstractDataSource#loadConfig()

@Override
public T loadConfig() throws Exception {return loadConfig(readSource());
}

查看 readSource() 实现:跳转 NacosDataSource.readSource() 中:

@Override
public String readSource() throws Exception {if (configService == null) {throw new IllegalStateException("Nacos config service has not been initialized or error occurred");}// 原来是获取nacos 中的配置return configService.getConfig(dataId, groupId, DEFAULT_TIMEOUT);
}

综上查看,Nacos 已经实现了读取配置的代码,那么我们只需要实现写入部分以及相关的配置即可。

2. 自己实现 Nacos 写入代码
1.定义 NacosWritableDataSource

依据读取部分的代码实现,利用 nacoscom.alibaba.nacos.api.config.ConfigService#publishConfig(java.lang.String, java.lang.String, java.lang.String) 方法,既会修改持久化文件,也会同步到对应的微服务。代码如下:

public class NacosWritableDataSource<T> implements WritableDataSource<T> {private NacosDataSourceProperties nacosDataSourceProperties;private ConfigService configService;private final Converter<T, String> configEncoder;private final Lock lock = new ReentrantLock(true);public NacosWritableDataSource(NacosDataSourceProperties nacosDataSourceProperties, Converter<T, String> configEncoder) {this.nacosDataSourceProperties = nacosDataSourceProperties;this.configEncoder = configEncoder;// 初始化 Nacos configServiceinitConfigService();}private void initConfigService(){try {this.configService = NacosFactory.createConfigService(buildProperties(nacosDataSourceProperties));} catch (NacosException e) {e.printStackTrace();}}private Properties buildProperties(NacosDataSourceProperties nacosDataSourceProperties) {Properties properties = new Properties();if (!StringUtils.isEmpty(nacosDataSourceProperties.getServerAddr())) {properties.setProperty(PropertyKeyConst.SERVER_ADDR, nacosDataSourceProperties.getServerAddr());} else {properties.setProperty(PropertyKeyConst.ACCESS_KEY, nacosDataSourceProperties.getAccessKey());properties.setProperty(PropertyKeyConst.SECRET_KEY, nacosDataSourceProperties.getSecretKey());properties.setProperty(PropertyKeyConst.ENDPOINT, nacosDataSourceProperties.getEndpoint());}if (!StringUtils.isEmpty(nacosDataSourceProperties.getNamespace())) {properties.setProperty(PropertyKeyConst.NAMESPACE, nacosDataSourceProperties.getNamespace());}if (!StringUtils.isEmpty(nacosDataSourceProperties.getUsername())) {properties.setProperty(PropertyKeyConst.USERNAME, nacosDataSourceProperties.getUsername());}if (!StringUtils.isEmpty(nacosDataSourceProperties.getPassword())) {properties.setProperty(PropertyKeyConst.PASSWORD, nacosDataSourceProperties.getPassword());}return properties;}@Overridepublic void write(T value) throws Exception {lock.lock();try {// 发布新配置configService.publishConfig(nacosDataSourceProperties.getDataId(), nacosDataSourceProperties.getGroupId(), this.configEncoder.convert(value), ConfigType.JSON.getType());} catch (Exception e) {throw e;} finally {lock.unlock();}}@Overridepublic void close() throws Exception {}}

上述只实现了数据配置更新与同步,我们还需要根据 Sentinel 的不用规则来区分具体是更新哪个文件,因此有下:

2.定义 SentinelNacosDataSourceHandler

public class SentinelNacosDataSourceHandler implements SmartInitializingSingleton {private final SentinelProperties sentinelProperties;public SentinelNacosDataSourceHandler(SentinelProperties sentinelProperties) {this.sentinelProperties = sentinelProperties;}//实现SmartInitializingSingleton 的接口后,当所有非懒加载的单例Bean 都初始化完成以后,Spring 的IOC 容器会调用该接口的 afterSingletonsInstantiated() 方法@Overridepublic void afterSingletonsInstantiated() {sentinelProperties.getDatasource().values().forEach(this::registryWriter);}private void registryWriter(DataSourcePropertiesConfiguration dataSourceProperties) {final NacosDataSourceProperties nacosDataSourceProperties = dataSourceProperties.getNacos();if (nacosDataSourceProperties == null) {return;}final RuleType ruleType = nacosDataSourceProperties.getRuleType();// 通过数据源配置的 ruleType 来注册数据源switch (ruleType) {case FLOW:WritableDataSource<List<FlowRule>> flowRuleWriter = new NacosWritableDataSource<>(nacosDataSourceProperties, JSON::toJSONString);WritableDataSourceRegistry.registerFlowDataSource(flowRuleWriter);break;case DEGRADE:WritableDataSource<List<DegradeRule>> degradeRuleWriter = new NacosWritableDataSource<>(nacosDataSourceProperties, JSON::toJSONString);WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWriter);break;case PARAM_FLOW:WritableDataSource<List<ParamFlowRule>> paramFlowRuleWriter = new NacosWritableDataSource<>(nacosDataSourceProperties, JSON::toJSONString);ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWriter);break;case SYSTEM:WritableDataSource<List<SystemRule>> systemRuleWriter = new NacosWritableDataSource<>(nacosDataSourceProperties, JSON::toJSONString);WritableDataSourceRegistry.registerSystemDataSource(systemRuleWriter);break;case AUTHORITY:WritableDataSource<List<AuthorityRule>> authRuleWriter = new NacosWritableDataSource<>(nacosDataSourceProperties, JSON::toJSONString);WritableDataSourceRegistry.registerAuthorityDataSource(authRuleWriter);break;default:break;}}
}
3. Spring IOC 管理 SentinelNacosDataSourceHandler
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(SentinelAutoConfiguration.class)
public class SentinelNacosDataSourceConfiguration {@Bean@ConditionalOnMissingBeanpublic SentinelNacosDataSourceHandler sentinelNacosDataSourceHandler(SentinelProperties sentinelProperties){return new SentinelNacosDataSourceHandler(sentinelProperties);}}
4. 配置文件

bootstrap.yml 中的配置文件内容如下:

spring:application:name: spring-cloud-sentinel-demo  #微服务名称cloud:nacos:config:  #配置nacos配置中心地址server-addr: 192.168.0.123:8847username: nacospassword: nacosfile-extension: yml   # 指定配置文件的扩展名为ymlnamespace: 6a7dbc5f-b376-41c6-a282-74ad4fd4829b

nacos 中微服务对应的配置文件内容如下:(也就是 application.yml ):

server:port: 8800spring:application:name: spring-cloud-sentinel-demo  #微服务名称cloud:nacos:  #配置nacos注册中心地址discovery:server-addr: 192.168.0.123:8847username: nacospassword: nacossentinel:transport:dashboard: 192.168.0.123:8091datasource:flow-rules: #流控规则nacos:server-addr: 192.168.0.123:8847namespace: 6a7dbc5f-b376-41c6-a282-74ad4fd4829busername: nacospassword: nacosdataId: ${spring.application.name}-flow-rulesgroupId: SENTINEL_GROUP   # 注意groupId对应Sentinel Dashboard中的定义data-type: jsonrule-type: flowdegrade-rules: #降级规则nacos:server-addr: 192.168.0.123:8847namespace: 6a7dbc5f-b376-41c6-a282-74ad4fd4829bdataId: ${spring.application.name}-degrade-rulesgroupId: SENTINEL_GROUPdata-type: jsonrule-type: degradeparam-flow-rules:nacos:server-addr: 192.168.0.123:8847namespace: 6a7dbc5f-b376-41c6-a282-74ad4fd4829bdataId: ${spring.application.name}-param-flow-rulesgroupId: SENTINEL_GROUPdata-type: jsonrule-type: param-flowauthority-rules:nacos:server-addr: 192.168.0.123:8847namespace: 6a7dbc5f-b376-41c6-a282-74ad4fd4829bdataId: ${spring.application.name}-authority-rulesgroupId: SENTINEL_GROUPdata-type: jsonrule-type: authoritysystem-rules:nacos:server-addr: 192.168.0.123:8847namespace: 6a7dbc5f-b376-41c6-a282-74ad4fd4829bdataId: ${spring.application.name}-system-rulesgroupId: SENTINEL_GROUPdata-type: jsonrule-type: system
3. 测试
1. 在 Sentinel Dashboard 新建流控规则:

在这里插入图片描述
查看 Nacos 配置中心,在对应的 namespace 下多了一个配置文件:spring-cloud-sentinel-demo-flow-rules 因为在上述文件中指定了 flow-rules 数据源的 namespacegroup
在这里插入图片描述查看此配置文件的详情可以看到:内容就是刚才流控规则的序列化内容:
在这里插入图片描述
综上,Sentinel Dashboard 新建的规则可以成功序列化到 Nacos 的配置中。

2. 在 Nacos 控制台修改对应的 count,在Sentinel Dashboard 查看是否同步显示:

修改前先查看Sentinel Dashboard 目前流控的阈值为2:
在这里插入图片描述
修改Nacos 中 spring-cloud-sentinel-demo-flow-rules 的配置,并发布:
在这里插入图片描述
修改后查看 Sentinel Dashboard 目前流控的阈值为3:
在这里插入图片描述
测试流控效果,已可以正常限流:
在这里插入图片描述

4. 其他规则也类似于流控规则

四、总结

最后附上这部分源码梳理图,可以结合上述内容一起理解。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/248212.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php怎么输入一个变量,http常用的两种请求方式getpost(ctf基础)

php是网页脚本语言&#xff0c;网页一般支持两种提交变量的方式&#xff0c;即get和post get方式传参 直接在网页URL的后面写上【?a1027】&#xff0c;如果有多个参数则用&符号连接&#xff0c; 如【?a10&b27】 post方式传参 需要借助插件&#xff0c;ctfer必备插…

STM32——DMA

STM32——DMA 1.DMA介绍 什么是DMA&#xff1f; DMA(Direct Memory Access&#xff0c;直接存储器访问) 提供在外设与内存、存储器和存储器、外设与外设之间的高速数据传输使用。它允许不同速度的硬件装置来沟通&#xff0c;而不需要依赖于CPU&#xff0c;在这个时间中&…

SpringBoot+SqlServer查询接口

SpringBootSqlServer查询接口 文章目录 SpringBootSqlServer查询接口1. pom环境配置2. common工具包3. 实体类接口映射4. Service层Controller层 需求&#xff1a;根据站号查询前一个小时的所有数据&#xff0c;将数据返回格式为Map<String,List<Map<String,String>…

滴滴开源小程序框架 Mpx 新特性:局部运行时能力增强

Mpx 是滴滴开源的一款增强型跨端小程序框架&#xff0c;自 2018 年立项开源以来如今已经进入第六个年头&#xff0c;在这六年间&#xff0c;Mpx 根植于业务&#xff0c;与业务共同成长&#xff0c;针对小程序业务开发中遇到的各类痛点问题提出了解决方案&#xff0c;并在滴滴内…

Android中下载 HAXM 报错 Intel® HAXM installation failed,如何解决?

最近在搭建 Flutter 环境&#xff0c;但是在 Android Studio 中安装 Virtual Device 时&#xff0c;出现了一个 问题 Intel HAXM installation failed. To install Intel HAXM follow the instructions found at: https://github.com/intel/haxm/wiki/Installation-Instructio…

基于ldap实现登录认证

最近开发的应用需要外协人员实现登录认证&#xff0c;外协人员的密码等信息已经录入到ldap, 需要连接ldap进行登录认证。下面先介绍一下登录的网络旅程图。 一.nginx实现AES加密 nginx请求处理入口&#xff08;前端请求为json格式&#xff09; location /aes {default_type te…

adb测试冷启动和热启动 Permission Denial解决

先清理日志 adb shell logcat -c 打开手机模拟器中的去哪儿网&#xff0c;然后日志找到包名和MainActivity adb shell logcat |grep Main com.Qunar/com.mqunar.atom.alexhome.ui.activity.MainActivity 把手机模拟器的去哪儿的进程给杀掉 执行 命令 adb shell am start -W…

方法、数组

方法 是语句的集合&#xff0c;在一起执行一个功能 它是解决一类问题的步骤的有序集合 包含于类或对象中 在程序中创建&#xff0c;在其他地方被引用 设计方法的原则&#xff1a;方法的本意是功能块&#xff0c;就是实现某一个功能的语句块的集合。设计时&#xff0c;最好保持…

Vue3+Vite使用Puppeteer进行SEO优化(SSR+Meta)

1. 背景 【笑小枫】https://www.xiaoxiaofeng.com上线啦 资源持续整合中&#xff0c;程序员必备网站&#xff0c;快点前往围观吧~ 我的个人博客【笑小枫】又一次版本大升级&#xff0c;虽然知道没有多少访问量&#xff0c;但我还是整天没事瞎折腾。因为一些功能在Halo上不太好实…

Unity中URP下额外灯角度衰减

文章目录 前言一、额外灯中聚光灯的角度衰减二、AngleAttenuation函数的传入参数1、参数&#xff1a;spotDirection.xyz2、_AdditionalLightsSpotDir3、参数&#xff1a;lightDirection4、参数&#xff1a;distanceAndSpotAttenuation.zw5、_AdditionalLightsAttenuation 三、A…

哪吒汽车与经纬恒润合作升级,中央域控+区域域控将于2024年落地

近日&#xff0c;在2024哪吒汽车价值链大会上&#xff0c;哪吒汽车与经纬恒润联合宣布合作升级&#xff0c;就中央域控制器和区域域控制器展开合作&#xff0c;合作成果将在山海平台新一代车型上发布。 哪吒汽车首席技术官戴大力、经纬恒润副总裁李伟 经纬恒润在智能驾驶领域拥…

Springboot自定义线程池实现多线程任务

1. 在启动类添加EnableAsync注解 2.自定义线程池 package com.bt.springboot.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTask…

MySQL原理(二)存储引擎(1)概述

一、存储引擎介绍 1、概念&#xff1a; &#xff08;1&#xff09;MySQL中的数据用各种不下同的技术存储在文件中&#xff0c;每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力&#xff0c;这些不同的技术以及配套的功能在MySQL中称为存储引擎…

@Async结合CompletableFuture实现主线程阻塞,CompletableFuture并发执行任务

Async结合CompletableFuture实现主线程阻塞&#xff0c;CompletableFuture并发执行任务 项目开发中经常会遇到业务需要多任务处理的场景&#xff0c;比如目前我除了的业务就是如此。 我要提供给客户端一个批量查询第三方数据的接口&#xff0c;由于是调用第三方的接口&#xf…

正则表达式 文本三剑客

一 正则表达式&#xff1a; 由一类特殊字符及文本字符所编写的模式&#xff0c;其中有些字符&#xff08;元字符&#xff09;不表示字符字面意义&#xff0c;而表示控制或通配的功能&#xff0c;类似于增强版的通配符功能&#xff0c;但与通配符不同&#xff0c;通配符功能是用…

分享4款不能错过的修改照片尺寸的软件!

在当今这个数字化时代&#xff0c;照片已经成为我们分享生活、表达观点的重要方式。但是&#xff0c;你是否曾遇到过这样的问题&#xff1a;一张精美的照片因为尺寸不合适而无法在朋友圈中展现出最佳效果&#xff1f;不用担心&#xff0c;今天我们就来聊聊那些可以帮助你轻松修…

漏洞原理远程命令执行

漏洞原理远程命令/代码执行 远程命令执行函数&#xff08;Remote Command Execution Function&#xff09;是指在一个网络环境中&#xff0c;通过远程执行命令来控制另一个计算机系统或设备的功能。 远程命令执行函数可以通过网络协议&#xff08;如SSH、Telnet、RPC等&#x…

wpf 数据转换(Bytes 转 KB MB GB)

效果 后端 using ProCleanTool.Model; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Data;namespace P…

SkyWalking+es部署与使用

第一步下载skywalking :http://skywalking.apache.org/downloads/ 第二步下载es:https://www.elastic.co/cn/downloads/elasticsearch 注&#xff1a;skywalking 和es要版本对应&#xff0c;可从下面连接查看版本对应关系&#xff0c;8.5.0为skywalking 版本号 Index of /di…

keepalived+nginx双主热备(有问题私信)

keepalivednginx双主热备 前言keepalivednginx双主热备keepalivednginx双主热备部署安装nginx安装keepalived修改master节点的keepalived配置文件 修改backup节点的keeepalived配置文件配置keepalived主备配置keepalived双主热备 前言 有关keepalived和nginx的一些工作原理&am…