Sentinel Dashboard集成Nacos

news/2024/5/19 19:18:55

1.前言

当项目上Sentinel Dashboard做流量监控的时候,我们可以通过Sentinel控制台修改限流配置,但当我们使用Nacos作为配置中心动态配置流控规则的时候,问题就来了。

首先我们要明白,Sentinel Dashboard的配置是从机器的内存中加载的,如果使用Nacos、Apollo、Zookeeper等作为我们动态加载限流规则的配置中心的时候,我们的配置信息流向是这样的:

就是说客户端从配置中心获取配置,Sentinel Dashboard又从客户端机器的内存中获取配置。

在这种情况下,Sentinel Dashboard可以修改配置,Nacos也可以修改配置,这就会存在数据一致性问题,我们可以从两方面考虑

1)Nacos修改了配置,Sentinel Dashboard会同步更新吗?答案是肯定的,因为Nacos配置变更会通知客户端,客户端配置变更后也会通知Sentinel Dashboard

2)如果在Sentinel Dashboard修改了配置会通知Nacos吗?答案是不会。但是可以通过修改源码实现。

Sentinel控制台在做流控规则的时候,都会调用Sentinel-Dashboard源码中的 一个名叫:FlowControllerV1的接口类,因为流控规则的所有操作,调用的 接口都是如图所示:

这个路径对应的就是FlowControllerV1这个类,但是同时还存在一个 FlowControllerV2的接口类,这个类主要提供的是流控规则的CURD,这两者有啥区别呢? 

区别在于:V2可以实现指定数据源的规则拉取和发布,这也就意味着Sentinel-Dashboard可以从Nacos等配置中心进行相互通信,从而实现数据一致性,Sentinel开发者已经做好封装,我们改一下源码配置一下就好了(后面会有教程)。这样我们的配置关系就变成了了这样:

2.实战:Sentinel Dashboard集成Nacos

第一步:下载Sentinel源码,本案例用的是Sentinel-v1.8.6

Sentinel官网下载地址:

https://github.com/alibaba/Sentinel/releases

下载好之后,解压,import project,可以看到sentinel-dashboard就是我们要改动的spring-boot项目

 

 第二步:将pom.xml中的sentinel-datasource-nacos的scope去掉

 第三步:进入resources/app/scripts/directives/sidebar/sidebar.html,全局搜一下“dashboard.flowV1”,替换成"dashboard.flow",也就是将V1去除:去除之后就 会调用FlowControllerV2中的CURD的接口

 其实Sentinel的开发者已经做好相关的适配,如下图,可以支持集成Apollo、Nacos、Zeekeeper,我们现在是以Nacos为例,进入src/test/java/com.alibaba.csp.sentinel.dashboard.rule.nacos目录,将整个nacos目录及其相关文件复制到src/main/java/com.alibaba.csp.sentinel.dashboard.rule.nacos

注:代码的红叉是因为我复制过去了,相同包名相同class导致的,不必在意,实在强迫症的话,可以把test里面的这几个删掉就好了,不删也不影响运行

 复制过来之后,如下图:

其中NacosConfigUtil就一些常量,我自定义了些常量并改名为NacosConfigConstant了,不在意细节

1.NacosConfigConstant.java

package com.alibaba.csp.sentinel.dashboard.rule.nacos;public class NacosConfigConstant { public static final String DATA_ID_POSTFIX="-flow-rules";public static final String GROUP_ID="SENTINEL_GROUP";  
}

 2.配置nacos相关配置

 2.1: application.properties添加nacos配置:

#config my nacos
sentinel.nacos.serverAddr=192.168.1.105:8848
sentinel.nacos.namespace=
sentinel.nacos.groupId=SENTINEL_GROUP

2.2: 新建Nacos配置类NacosPropertiesConfiguration.java

package com.alibaba.csp.sentinel.dashboard.rule.nacos;import org.springframework.boot.context.properties.ConfigurationProperties;@ConfigurationProperties(prefix = "sentinel.nacos")
public class NacosPropertiesConfiguration {private String serverAddr;private String dataId;private String groupId;private String namespace;public String getServerAddr() {return serverAddr;}public void setServerAddr(String serverAddr) {this.serverAddr = serverAddr;}public String getDataId() {return dataId;}public void setDataId(String dataId) {this.dataId = dataId;}public String getGroupId() {return groupId;}public void setGroupId(String groupId) {this.groupId = groupId;}public String getNamespace() {return namespace;}public void setNamespace(String namespace) {this.namespace = namespace;}}

3.FlowRuleNacosProvider.java,稍微改动了一下,如下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos;import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.utils.StringUtils;@Service("flowRuleNacosProvider")
public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {@Autowiredprivate NacosPropertiesConfiguration nacosPropertiesConfiguration;@Autowiredprivate ConfigService configService;@Autowiredprivate Converter<String, List<FlowRuleEntity>> converter;/*** @Description: 通过ConfigService.getConfig方法从NacosConfigServer中读取指定配置信息,通过converter转化为FlowRule规则* @Author: LiJianhong* @Param: [appName]* @Return: java.util.List<com.alibaba.csp.sentinel.dashboard.datasource.entity.*          rule.FlowRuleEntity>*/@Overridepublic List<FlowRuleEntity> getRules(String appName) throws Exception {String dataId = appName + NacosConfigConstant.DATA_ID_POSTFIX; //user-service-flow-rulesString groupId = nacosPropertiesConfiguration.getGroupId();String rules = configService.getConfig(dataId, groupId, 3000);if (StringUtils.isEmpty(rules)) {return new ArrayList<>();}return converter.convert(rules);}
}

4.FlowRuleNacosPublisher.java,也是稍微改动了一下:

package com.alibaba.csp.sentinel.dashboard.rule.nacos;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;@Service("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {@Autowiredprivate NacosPropertiesConfiguration nacosPropertiesConfiguration;@Autowiredprivate ConfigService configService;@Autowiredprivate Converter<List<FlowRuleEntity>, String> converter;@Overridepublic void publish(String app, List<FlowRuleEntity> rules) throws Exception {AssertUtil.notEmpty(app, "appName connot be empty");if (rules == null) {return;}String dataId = new StringBuilder(app).append(NacosConfigConstant.DATA_ID_POSTFIX).toString();configService.publishConfig(dataId, nacosPropertiesConfiguration.getGroupId(), converter.convert(rules));}}

 5. 修改com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2,将注入的bean改成我们改过之后的bean

6.最后mvn clean package打包运行jar即可。

接下来是测试环节:

运行改动后的sentinel-dashboard 

首先,我在Nacos配置中心配置了dataId=user-service-flow-rules限流规则,如下:

[{"app": "user-service","clusterConfig": {"acquireRefuseStrategy": 0,"clientOfflineTime": 2000,"fallbackToLocalWhenFail": true,"flowId": 1001,"resourceTimeout": 2000,"resourceTimeoutStrategy": 0,"sampleCount": 10,"strategy": 0,"thresholdType": 1,"windowIntervalMs": 1000},"clusterMode": true,"controlBehavior": 0,"count": 30.0,"gmtModified": 1690385332131,"grade": 1,"id": 1001,"limitApp": "default","resource": "com.lee.demo.dubbo.demo.user.ISentinelService","strategy": 0},{"app": "user-service","clusterConfig": {"acquireRefuseStrategy": 0,"clientOfflineTime": 2000,"fallbackToLocalWhenFail": true,"flowId": 1002,"resourceTimeout": 2000,"resourceTimeoutStrategy": 0,"sampleCount": 10,"strategy": 0,"thresholdType": 0,"windowIntervalMs": 1000},"clusterMode": true,"controlBehavior": 0,"count": 10.0,"gmtModified": 1690373927810,"grade": 1,"id": 1002,"limitApp": "default","resource": "com.lee.demo.dubbo.demo.user.IHelloService","strategy": 0}
]

com.lee.demo.dubbo.demo.user.ISentinelService的count配置的是30

com.lee.demo.dubbo.demo.user.IHelloService的count配置的是10

然后看下Sentinel-Dashboard的限流规则是与Nacos一致的:

1)在Nacos修改配置查看Sentinel-Dashboard是否更新配置:

可以看到Sentinel-Dashboard的配置是更新了

 2)在Sentinel-Dashboard更新配置,检查是否同步到Nacos,这一步才是验证我们这么辛苦改代码的关键

 可以看到,Nacos成功同步了Sentinel-Dashboard的配置修改

注:我发现改了之后,在Sentinel-Dashboard对配置的CRUD之后,页面没有刷新,要我们手动刷新一下才会看到最新数据~~o(>_<)o ~~,这个我没有过多去排查前端的异常,毕竟我只是后端开发嘛。

至此,Sentinel-Dashboard集成Nacos案例演示完毕。

最后分享一下集成Nacos过程中遇到的问题:

1)Sentinel-Dashboard控制台可以新增限流规则同步Nacos,但是“修改”配置的时候弹出警告“失败”,没提示啥原因,经过debug才发现,是因为新增和修改都需要进行限流规则的参数校验,校验的必要参数如下:

private <R> Result<R> checkEntityInternal(FlowRuleEntity entity) {if (entity == null) {return Result.ofFail(-1, "invalid body");}if (StringUtil.isBlank(entity.getApp())) {return Result.ofFail(-1, "app can't be null or empty");}if (StringUtil.isBlank(entity.getLimitApp())) {return Result.ofFail(-1, "limitApp can't be null or empty");}if (StringUtil.isBlank(entity.getResource())) {return Result.ofFail(-1, "resource can't be null or empty");}if (entity.getGrade() == null) {return Result.ofFail(-1, "grade can't be null");}if (entity.getGrade() != 0 && entity.getGrade() != 1) {return Result.ofFail(-1, "grade must be 0 or 1, but " + entity.getGrade() + " got");}if (entity.getCount() == null || entity.getCount() < 0) {return Result.ofFail(-1, "count should be at lease zero");}if (entity.getStrategy() == null) {return Result.ofFail(-1, "strategy can't be null");}if (entity.getStrategy() != 0 && StringUtil.isBlank(entity.getRefResource())) {return Result.ofFail(-1, "refResource can't be null or empty when strategy!=0");}if (entity.getControlBehavior() == null) {return Result.ofFail(-1, "controlBehavior can't be null");}int controlBehavior = entity.getControlBehavior();if (controlBehavior == 1 && entity.getWarmUpPeriodSec() == null) {return Result.ofFail(-1, "warmUpPeriodSec can't be null when controlBehavior==1");}if (controlBehavior == 2 && entity.getMaxQueueingTimeMs() == null) {return Result.ofFail(-1, "maxQueueingTimeMs can't be null when controlBehavior==2");}if (entity.isClusterMode() && entity.getClusterConfig() == null) {return Result.ofFail(-1, "cluster config should be valid");}return null;}

因此我把Nacos配置中心的限流规则根据这个必要参数都配置了一下之后,再从Sentinel Dashboard修改配置成功了。


http://www.mrgr.cn/p/87432034

相关文章

基于解析法和遗传算法相结合的配电网多台分布式电源降损配置(Matlab实现)

目录 1 概述 2 数学模型 2.1 问题表述 2.2 DG的最佳位置和容量&#xff08;解析法&#xff09; 2.3 使用 GA 进行最佳功率因数确定和 DG 分配 3 仿真结果与讨论 3.1 33 节点测试配电系统的仿真 3.2 69 节点测试配电系统仿真 4 结论 1 概述 为了使系统网损达到最低值&a…

推荐用于学习RN原生模块开发的开源库—react-native-ble-manager

如题RN的原生模块/Native Modules的开发是一项很重要的技能&#xff0c;但RN官网的示例又比较简单&#xff0c;然后最近我接触与使用、还有阅读了react-native-ble-manager的部份源码&#xff0c;发现里边完全包含了一个Native Modules所涉及的知识点/技术点&#xff0c;故特推…

web自动化测试-PageObject 设计模式

为 UI 页面写测试用例时&#xff08;比如 web 页面&#xff0c;移动端页面&#xff09;&#xff0c;测试用例会存在大量元素和操作细节。当 UI 变化时&#xff0c;测试用例也要跟着变化&#xff0c; PageObject 很好的解决了这个问题。 使用 UI 自动化测试工具时&#xff08;包…

工程师是怎样对待开源

工程师如何对待开源 本文是笔者作为一个在知名科技企业内从事开源相关工作超过 20 年的工程师&#xff0c;亲身经历或者亲眼目睹很多工程师对待开源软件的优秀实践&#xff0c;也看到了很多 Bad Cases&#xff0c;所以想把自己的一些心得体会写在这里&#xff0c;供工程师进行…

呼吸灯——FPGA

文章目录 前言一、呼吸灯是什么&#xff1f;1、介绍2、占空比调节示意图 二、系统设计1、系统框图2、RTL视图 三、源码四、效果五、总结六、参考资料 前言 环境&#xff1a; 1、Quartus18.0 2、vscode 3、板子型号&#xff1a;EP4CE6F17C8 要求&#xff1a; 将四个LED灯实现循环…

无涯教程-jQuery - jQuery.post( url, data, callback, type)方法函数

jQuery.post(url&#xff0c;[data]&#xff0c;[callback]&#xff0c;[type])方法使用POST HTTP请求从服务器加载页面。 该方法返回XMLHttpRequest对象。 jQuery.post( url, [data], [callback], [type] ) - 语法 $.post( url, [data], [callback], [type] ) 这是此方法使…

ElasticSearch基本使用--ElasticSearch文章一

文章目录 官网学习必要性elasticsearch/kibana安装版本数据结构说明7.x版本说明ElasticSearch kibana工具测试后续我们会一起分析 官网 https://www.elastic.co/cn/ 学习必要性 1、在当前软件行业中&#xff0c;搜索是一个软件系统或平台的基本功能&#xff0c; 学习Elastic…

6.2.tensorRT高级(1)-第一个完整的分类器程序

目录 前言1. CNN分类器2. 补充知识2.1 知识点2.2 智能指针封装 总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT …

强化学习(EfficientZero)(应用于图像和声音)

目录 摘要 1.背景介绍 2.MCTS&#xff08;蒙特卡洛树搜索&#xff09;&#xff08;推理类模型&#xff0c;棋类效果应用好&#xff0c;控制好像也不错&#xff09; 3.MUZERO 4.EfficientZero&#xff08;基于MUZERO&#xff09; 展望 参考文献 摘要 在文中&#xff0c;基于…

版本适配好帮手 Android SDK Upgrade Assistant / Android Studio Giraffe新功能

首先是新版本一顿下载↓&#xff1a; Download Android Studio & App Tools - Android Developers 在Tools中找到Android SDK Upgrade Assistant 可以在此直接查看SDK升级相关信息&#xff0c;不用跑到WEB端去查看了。 例如看一下之前经常要对老项目维护的android 12蓝牙…

【C进阶】回调函数(指针进阶2,详解,小白必看)

目录 6. 函数指针数组 6.1简单计算器 6.2函数指针数组实现计算器 7. 指向函数指针数组的指针(仅作了解即可) 8.回调函数 8.1关于回调函数的理解​编辑 8.1.1用回调函数改良简单计算器 8.2qsort库函数的使用 8.2.1冒泡排序 8.2.2qsort的概念 8.3冒泡排序思想实现qsor…

PKG内容查看工具:Suspicious Package for Mac安装教程

Suspicious Package Mac版是一款Mac平台上的查看 PKG 程序包内信息的应用&#xff0c;Suspicious Package Mac版支持查看全部包内全部文件&#xff0c;比如需要运行的脚本&#xff0c;开发者&#xff0c;来源等等。 suspicious package mac使用简单&#xff0c;只需在选择pkg安…

开发和测试模型

瀑布模型 需求分析-计划-设计-编码-执行测试-运行维护 特点: 线性结构每个阶段只执行一次 其他模型的基础框架 缺点: 测试后置 前面的风险被推迟到测试阶段才被发现,项目大面积需要修改,工作量大 测试时间不够 没有充足的测试时间进行功能评估和需求功能比对,会将缺陷暴露给用…

代码版本管理工具 git

1. 去B站看视频学习&#xff0c;只看前39集&#xff1a; 01-Git概述&#xff08;Git历史&#xff09;_哔哩哔哩_bilibili 2.学习Linux系统文本编辑器的使用 vi编辑器操作指令分享 (baidu.com) (13条消息) nano编辑器的使用_SudekiMing的博客-CSDN博客 windows下载安装Git官…

使用贝叶斯滤波器通过运动模型和嘈杂的墙壁传感器定位机器人研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【C++】开源:Boost网络库Asio配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Asio网络库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次…

小程序----配置原生内置编译插件支持sass

修改project.config.json配置文件 在 project.config.json 文件中&#xff0c;修改setting 下的 useCompilerPlugins 字段为 ["sass"]&#xff0c; 即可开启工具内置的 sass 编译插件。 目前支持三个编译插件&#xff1a;typescript、less、sass 修改之后可以将原.w…

GNSS技术知识你知道多少?这些你或许还未掌握

GNSS信号频段 GNSS频谱图展示了不同的GNSS信号及其星座、载波频率、调制方案&#xff0c;以及所有这些信号在同一L波段频段内如何相互关联&#xff0c;是GNSS专业人员的必备工具&#xff0c;包括设计和开发GNSS系统的工程师&#xff0c;以及测试GNSS系统的工程师。 GNSS术语 …

基于深度学习的高精度课堂人脸检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度课堂人脸检测系统可用于日常生活中或野外来检测与定位课堂人脸目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的课堂人脸目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标…

shopee,lazada,etsy店群如何高效安全的管理

对于电商卖家来说&#xff0c;要经营多个店铺&#xff0c;管理多个账号是非常常见的操作。为了避免账号关联被平台识别出来&#xff0c;需要使用防关联的浏览器来进行操作 ​1、支持多平台 支持同时管理多个电商平台店铺&#xff0c;Shopee、Lazada、etsy、poshmark、vinted等&…