Sentinel Dashboard 接入 Nacos 动态数据源 Zuul 接入 Sentinel 实战

背景

Sentinel Dashboard 默认将限流、熔断等规则保存在内存中,然后同步给连接 Dashboard 的客户端,客户端也是保存在内存中。
那么如果当 Sentinel Dashboard 异常重启,那么之前配置的规则将全部丢失,需要重新进行配置。
其中,Sentinel 本身已经提供第三方组件作为动态数据源,如:Apollo、Nacos、Zookeeper。
因此,我们可以对 Sentinel Dashboard 进行改造,将规则存储在上述的中间件中,保证 Dashboard 重启不会丢失原有的所有规则配置。

改造

下载源码

因为我们需要对 Sentinel Dashboard 进行改造,所以需先下载源码下来,这里选择的版本为:1.8.6
image.png
下载源码后,我们可以发现在test下,是有 Apollo、Nacos 和 Zookeeper 作为数据源的代码,因此我们可以进行借鉴复用。
image.png
因为我们的微服务架构是:Spring Cloud Alibaba 系列的,所以注册中心和配置中心都是使用的 Nacos,所以下面将基于 Nacos 去改造 Sentinel Dashboard。

Sentinel Dashboard 接入 Nacos

test 中,Nacos 是通过调用 ConfigService 去查询规则和保存规则,虽然单元测试中代码仅仅是流控规则的代码,但是我们完全可以借鉴,毕竟现在仅仅是改造规则的保存和查询逻辑,整体方式都是一致的,仅仅需要找到其他规则所在代码,然后做替换即可。

自定义 DynamicRuleProvider & DynamicRulePulisher

DynamicRuleProvider

用于查询规则,我们借鉴 test 代码中的com.alibaba.csp.sentinel.dashboard.rule.nacos.FlowRuleNacosProvider即可,为所有规则都实现一遍,核心逻辑就是使用 Nacos 提供的ConfigService进行查询。

DynamicRulePublisher

用于新增/更新/删除规则,我们借鉴 test 代码中的com.alibaba.csp.sentinel.dashboard.rule.nacos.FlowRuleNacosPublisher即可,为所有规则都实现一遍,核心逻辑就是使用 Nacos 提供的ConfigService进行推送。

实现

由于我们仅仅调整规则的保存/更新/删除和查询逻辑,其余业务逻辑不调整,所以不管是那种规则,调整的逻辑都是一致的,可能不一样的仅仅是以下两点:

  1. 保存在 Nacos 中,不同规则的dataId不一样
  2. 从 Nacos 查询后,转化的实体对象不一致

因此,我们这里针对 Provider 和 Publisher 都抽象一个类,实现核心的保存逻辑和更新逻辑。不同规则只需要继承对应的抽象类,然后具体对应的规则dataId和查询实体泛型。
NacosConfigUtil:

/*** @author Eric Zhao* @since 1.4.0*/
public final class NacosConfigUtil {public static final String GROUP_ID = "SENTINEL_GROUP";// 保存到nacos中的文件后缀public static final String FLOW_DATA_ID_POSTFIX = "-flow-rules";public static final String DEGRADE_DATA_ID_POSTFIX = "-degrade-rules";public static final String SYSTEM_DATA_ID_POSTFIX = "-system-rules";public static final String AUTHORITY_DATA_ID_POSTFIX = "-authority-rules";public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-flow-rules";public static final String GATEWAY_FLOW_DATA_ID_POSTFIX = "-gw-flow-rules";public static final String GATEWAY_API_FLOW_DATA_ID_POSTFIX = "-gw-api-group-rules";//public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-rules";public static final String CLUSTER_MAP_DATA_ID_POSTFIX = "-cluster-map";/*** cc for `cluster-client`*/public static final String CLIENT_CONFIG_DATA_ID_POSTFIX = "-cc-config";/*** cs for `cluster-server`*/public static final String SERVER_TRANSPORT_CONFIG_DATA_ID_POSTFIX = "-cs-transport-config";public static final String SERVER_FLOW_CONFIG_DATA_ID_POSTFIX = "-cs-flow-config";public static final String SERVER_NAMESPACE_SET_DATA_ID_POSTFIX = "-cs-namespace-set";private NacosConfigUtil() {}
}

NacosRuleProvider:

/*** Nacos RuleProvider 抽象类* @author winfun* @since 2023/9/29**/
public abstract class NacosRuleProvider<T extends RuleEntity>  implements DynamicRuleProvider<List<T>> {@Autowiredprotected ConfigService configService;@Autowiredprotected Converter<String, List<T>> converter;@Overridepublic List<T> getRules(String appName) throws Exception {String rules = configService.getConfig(appName + getDataIdPostfix(),NacosConfigUtil.GROUP_ID, 3000);if (StringUtil.isEmpty(rules)) {return new ArrayList<>();}return converter.convert(rules);}/*** dataId 后缀,参考 com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil* @return dataId 后缀*/public abstract String getDataIdPostfix();
}

NacosRulePublisher:

/*** Nacos RulePublisher 抽象类* @author winfun* @since 2023/9/29**/
public abstract class NacosRulePublisher<T extends RuleEntity> implements DynamicRulePublisher<List<T>> {@Autowiredprotected ConfigService configService;@Autowiredprotected Converter<List<T>, String> converter;@Overridepublic void publish(String app, List<T> rules) throws Exception {AssertUtil.notEmpty(app, "app name cannot be empty");if (rules == null) {return;}configService.publishConfig(app + getDataIdPostfix(),NacosConfigUtil.GROUP_ID, converter.convert(rules));}/*** dataId 后缀,参考 com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil* @return dataId 后缀*/public abstract String getDataIdPostfix();
}

后续不同的规则,分别创建子类继承上面的抽象类即可。
image.png
这里拿网关做例子:

/*** 网关 RulePublisher* @author winfun* @since 2023/9/29**/
@Component("nacosGatewayFlowRulePublisher")
public class NacosGatewayFlowRulePublisher extends NacosRulePublisher<GatewayFlowRuleEntity> {@Overridepublic String getDataIdPostfix() {return NacosConfigUtil.GATEWAY_FLOW_DATA_ID_POSTFIX;}
}
/*** 网关 RuleProvider* @author winfun* @since 2023/9/29**/
@Component("nacosGatewayFlowRuleProvider")
public class NacosGatewayFlowRuleProvider extends NacosRuleProvider<GatewayFlowRuleEntity> {@Overridepublic String getDataIdPostfix() {return NacosConfigUtil.GATEWAY_FLOW_DATA_ID_POSTFIX;}
}

Controller 接口调整

上面,我们仅仅为各种规则的保存和查询创建了对应的 RulePublisher 和 RuleProvider,我们还需要对页面的接口进行调整,将接口中保存和查询规则的代码调整。
image.png
改动逻辑:将代码中使用 SentinelApiClient 进行规则查询和保存的逻辑代码,改为 Nacos 对应的 Provider 和 Publisher
其中对应关系:

  1. GatewayApiController:使用 nacosApiDefinitionProvider 和 nacosApiDefinitionPublisher
  2. GatewayFlowRuleController:使用 nacosGatewayFlowRuleProvider 和 nacosGatewayFlowRulePublisher
  3. FlowControllerV2:使用 nacosFlowRuleProvider 和 nacosFlowRulePublisher
  4. AuthorityRuleController:使用 authorityRuleNacosProvider 和 authorityRuleNacosPublisher
  5. DegradeController:使用 nacosDegradeRuleProvider 和 nacosDegradeRulePublisher
  6. ParamFlowRuleController:使用 nacosParamFlowRuleProvider 和 nacosParamFlowRulePublisher
  7. SystemController:使用 nacosSystemRuleProvider 和 nacosSystemRulePublisher

以 GatewayFlowRuleController 为例子:
注释掉 SentinelApiClient,引入对应 Nacos 的 RulePublisher 和 RuleProvider:
image.png
查询代码调整:
image.png
新增/更新/删除代码调整,其实就是更新推送规则的逻辑:
image.png

启动应用

添加 Nacos 配置:

nacos.serverAddr=127.0.0.1:8848
nacos.namespace=1ee594f6-001f-4d68-9852-ca6fce6039c9

groupId默认使用 SENTINEL_GROUP,配置在 NacosConfigUtil 中

启动 Spring 应用:
image.png
应用启动后,由于还没有 Sentinel 客户端接入,因此登录 Web 端后,是没有东西可以显示的。
image.png

Sentinel 客户端接入

这里用 Zuul 网关服务作为例子。

Zuul 网关接入 Sentinel

引入Maven依赖:

<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-zuul-adapter</artifactId>
</dependency>
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-transport-simple-http</artifactId>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency><!-- 动态数据源 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
</dependency>
<!--  nacos 数据源 -->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

添加配置:

spring:cloud:nacos:server-addr: 127.0.0.1:8848password: nacosusername: nacosdiscovery:namespace: 1ee594f6-001f-4d68-9852-ca6fce6039c9enabled: trueconfig:namespace: 1ee594f6-001f-4d68-9852-ca6fce6039c9enabled: falsefile-extension: ymlsentinel:filter:enabled: truetransport:port: 8719dashboard: 127.0.0.1:18181datasource:# 限流flow:nacos:server-addr: ${spring.cloud.nacos.server-addr}namespace: ${spring.cloud.nacos.discovery.namespace}dataId: ${spring.application.name}-flow-rulesgroupId: SENTINEL_GROUPdata-type: jsonrule-type: flow# 熔断degrade:nacos:server-addr: ${spring.cloud.nacos.server-addr}namespace: ${spring.cloud.nacos.discovery.namespace}dataId: ${spring.application.name}-degrade-rulesgroupId: SENTINEL_GROUPdata-type: jsonrule-type: degrade

自定义降级Provider:

/*** CustomZuulBlockFallbackProvider* @author winfun* @since 2023/10/3**/
@Slf4j
@Component
public class CustomZuulBlockFallbackProvider implements ZuulBlockFallbackProvider {@Overridepublic String getRoute() {return "*";}@Overridepublic BlockResponse fallbackResponse(String route, Throwable cause) {RequestContext ctx = RequestContext.getCurrentContext();HttpServletRequest request = ctx.getRequest();String url = request.getRequestURL().toString();if (cause instanceof FlowException) {log.warn("url:{} 触发限流",url);return new BlockResponse(429, "Sentinel触发限流", route);} else if (cause instanceof DegradeException) {log.warn("url:{} 触发熔断",url);return new BlockResponse(429, "Sentinel触发熔断", route);} else {return new BlockResponse(500, "系统异常", route);}}
}

启动应用,并随便调用一个接口,调用后 Sentinel 客户端就会将相关信息上报给 Sentinel Dashboard:
image.png

设置 Route 类型的限流规则和熔断规则

在 Sentinel Dashboard 新增限流规则和熔断规则:
image.png
image.png
Nacos 在对应的 namespace 中也会出现对应的配置:
image.png
调用报错的接口,当调用第一次失败后,第二次就会触发熔断规则:
image.png

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

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

相关文章

二叉搜索树--查询节点-力扣 700 题

例题细节讲过(二叉搜索树的基础操作-CSDN博客)&#xff0c;下面给出递归实现 public TreeNode searchBST(TreeNode node, int val) {if(node null) {return null;}if(val < node.val) {return searchBST(node.left, val);} else if(node.val < val) {return searchBST(…

VsCode同时编译多个C文件

VsCode默认只能编译单个C文件&#xff0c;想要编译多个文件&#xff0c;需要额外进行配置 第一种方法 ——> 通过手动指定要编译的文件 g -g .\C文件1 .\C文件2 -o 编译后exe名称 例如我将demo.c和extern.c同时编译得到haha.exe g -g .\demo.c .\extern.c -o haha 第二种…

解决github加载过慢问题

github打不开怎么办&#xff1f;看到这篇文章&#xff0c;一切都稳了&#xff01; DNS被污染&#xff0c;一句话&#xff0c;修改系统hosts文件&#xff01; 1.hosts文件在哪&#xff1f;C:\Windows\System32\drivers\etc 2.用记事本打开hosts&#xff0c;在最后加入以下两行…

中科院提出“思维传播”,极大增强ChatGPT等模型复杂推理能力

中国科学院自动化研究所与耶鲁大学计算机系研究人员联合发布了&#xff0c;一份名为《思维传播:用大型语言模型进行基于类比的复杂推理》的论文。 ChatGPT等大型语言模型展示出了超强的创造能力&#xff0c;只需简单的文本提示就能生成小说、营销创意、简历等各种文本内容。但…

VUE3基础知识梳理

VUE3基础知识梳理 一、vue了解和环境搭建1.vue是什么&#xff1a;cn.vuejs.org/vuejs.org2.渐进式框架3.vue的版本4.vueAPI的风格5.准备环境5.1.创建vue项目5.2.vue的目录结构 二、vue3语法1.干净的vue项目2.模板语法2.1 文本插值2.2属性绑定2.3条件渲染2.4列表渲染2.5通过key管…

Python自动化测试框架pytest的详解安装与运行

这篇文章主要为大家介绍了Python自动化测试框架pytest的简介以及安装与运行&#xff0c;有需要的朋友可以借鉴参考下希望能够有所帮助&#xff0c;祝大家多多进步 1. pytest的介绍 pytest是一个非常成熟的全功能的python测试工具&#xff0c;它主要有以下特征&#xff1a; 简…

Linux C select 的学习

一. select 系统调用 1. 函数说明 #include <sys/select.h> #include <sys/time.h>int select(int nfds, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);nfds: 是一个整数值&#xff0c;是指集合中所有文件描述符的范围&#…

日常学习记录随笔-zabix实战

使用zabix结合 实现一套监控报警装置 不管是web开发还是大数据开发 我们的离线项目还是实时项目也好&#xff0c;都需要把我们的应用提交到我们服务器或者容器中去执行 整个应用过程中怎么保证线上整体环境的稳定运行 监控很重要 现在比较主流的就是 普罗米修斯以及zabix 我要做…

Docker-harbor私有仓库部署与管理

搭建本地私有仓库 #首先下载 registry 镜像 docker pull registry #在 daemon.json 文件中添加私有镜像仓库地址 vim /etc/docker/daemon.json { "insecure-registries": ["20.0.0.50:5000"], #添加&#xff0c;注意用逗号结…

Apache Solr9.3 快速上手

Apache Solr 简介 Solr是Apache的顶级开源项目&#xff0c;使用java开发 &#xff0c;基于Lucene的全文检索服务器。 Solr比Lucene提供了更多的查询语句&#xff0c;而且它可扩展、可配置&#xff0c;同时它对Lucene的性能进行了优化。 安装 下载 : 下载地址解压 : tar -zxv…

Unity可视化Shader工具ASE介绍——6、通过例子说明ASE节点的连接方式

大家好&#xff0c;我是阿赵。继续介绍Unity可视化Shader编辑插件ASE的用法。上一篇已经介绍了很多ASE常用的节点。这一篇通过几个小例子&#xff0c;来看看这些节点是怎样连接使用的。   这篇的内容可能会比较长&#xff0c;最终是做了一个遮挡X光的效果&#xff0c;不过把这…

Docker部署gitlab_ce(避坑版---社区版)

1 下载docker 2 下载gitlab镜像 3 运行 4 进入容器内部修改 5 在浏览器里访问 6 修改root密码&#xff08;如果忘记请修改&#xff09; 1 下载docker # 安装依赖 yum install -y yum-utils device-mapper-persistent-data lvm2# 设置yum源 yum-config-manager --add-repo https…

语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆

文章目录 mask图像介绍步骤代码 mask图像介绍 根据 mask 图像来画分割对象的外接椭圆是一种常见的图像分割任务。Mask 图像通常是一个二值图像&#xff0c;其中包含了感兴趣对象的像素。通常情况下&#xff0c;白色像素表示对象&#xff0c;黑色像素表示背景。 步骤 以下是一…

Linux和UNIX的关系及区别

UNIX 与 Linux 之间的关系是一个很有意思的话题。在目前主流的服务器端操作系统中&#xff0c;UNIX 诞生于 20 世纪 60 年代末&#xff0c;Windows 诞生于 20 世纪 80 年代中期&#xff0c;Linux 诞生于 20 世纪 90 年代初&#xff0c;可以说 UNIX 是操作系统中的"老大哥&…

Python利用jieba分词提取字符串中的省市区(字符串无规则)

目录 背景库&#xff08;jieba&#xff09;代码拓展结尾 背景 今天的需求就是在一串字符串中提取包含&#xff0c;省、市、区&#xff0c;该字符串不是一个正常的地址;,如下字符串 "安徽省、浙江省、江苏省、上海市,冷运标快首重1kg价格xx元,1.01kg(含)-5kg(不含)续重价…

【web实现右侧弹窗】JS+CSS如何实现右侧缓慢弹窗动态效果『附完整源码下载』

文章目录 写在前面涉及知识点页面效果1、页面DOM创建1.1创建底层操作dom节点1.2 创建存放弹窗dom节点 2、页面联动功能实现&#xff08;关闭与弹出&#xff09;2.1 点击非右侧区域实现关闭2.2 点击叉叉及关闭按钮实现关闭功能 3、完整源码包下载3.1百度网盘3.2 123云盘3.3邮箱留…

按键中断小灯蜂鸣器风扇

按键1实现小灯亮灭&#xff0c;按键2实现蜂鸣器&#xff0c;安静3实现风扇 src/key_it.c #include"key_it.h"void key3_it_config() {//RCC使能GPIOF时钟RCC->MP_AHB4ENSETR | (0x1<<5);GPIOF->MODER & (~(0x3<<16));EXTI->EXTICR3 &…

基于若依ruoyi-nbcio支持flowable流程增加自定义业务表单(二)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 之前讲了自定义业务表单&#xff0c;现在讲如何与流程进行关联 1、后端部分 WfCustomFormMapper.xml &…

Flink-SQL join 优化 -- MiniBatch + local-global

背景 问题1. 近期在开发flink-sql期间&#xff0c;发现数据在启动后&#xff0c;任务总是进行重试&#xff0c;运行一段时间后&#xff0c;container heartbeat timeout&#xff0c;内存溢出(GC overhead limit exceede) &#xff0c;作业无法进行正常工作 023-10-07 14:53:3…

Commonjs与ES Module

commonjs 1 commonjs 实现原理 commonjs每个模块文件上存在 module&#xff0c;exports&#xff0c;require三个变量,然而这三个变量是没有被定义的&#xff0c;但是我们可以在 Commonjs 规范下每一个 js 模块上直接使用它们。在 nodejs 中还存在 __filename 和 __dirname 变…