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;在最后加入以下两行…

react闪屏问题以及useEffect和useLayoutEffect的对比使用

二者对比 useEffect()是在渲染被绘制到屏幕之后执行的&#xff0c;是异步的&#xff1b;useLayoutEffect()是在渲染之后但在屏幕更新之前执行的&#xff0c;是同步的。 二者均是等待jsx执行完毕后再执行&#xff0c;但useLayoutEffect()在useEffect()之前触发。 大部分情况下…

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

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

自动监控网站可用性并发送通知的 Bash 脚本

在现代的互联网世界中&#xff0c;网站的可用性对于业务的成功至关重要。如果您是一个网站管理员或负责监控网站运行状况的工程师&#xff0c;那么您知道及时发现并解决问题对于确保用户满意度至关重要。如何使用 Bash 脚本来监控多个网站的可用性&#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; 简…

读书笔记—《如何阅读一本书》

读书笔记—《如何阅读一本书》 一、阅读的层次1、主动阅读的基础一个阅读者要提出的四个基本问题 2、基础阅读&#xff08;第一层&#xff09;3、检视阅读&#xff08;第二层&#xff09;4、分析阅读&#xff08;第三层&#xff09; 二、阅读不同读物的方法三、阅读的最终目标1…

AF_UNIX和127.0.0.1(AF_INET)回环地址写数据速度对比(二)

之前写了篇博客&#xff1a;AF_UNIX和127.0.0.1(AF_INET)回环地址写数据速度对比 然后利用的是发送端读取大文件&#xff0c;接收方接收并保存为文件的方式进行测试&#xff0c;结果发现&#xff0c;AF_UNIX并未比127.0.0.1(AF_INET)回环地址优秀&#xff0c;若单次发送的字节数…

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…

day04-前台首页、导出项目依赖

1 前台首页 1.1 Header.vue 1.2 Footer.vue 1.3 Banner.vue 1.4 HomeView.vue 1.5 轮播图接口打通 2 导出项目依赖 3 抽取返回格式 1 前台首页 -在项目的components文件夹下&#xff1a; 新建&#xff1a;Header.vueFooter.vueBanner.vue1.1 Header.vue <template>&…

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…

【动手学深度学习-Pytorch版】BERT预测系列——用于预测的BERT数据集

本小节的主要任务即是将wiki数据集转成BERT输入序列&#xff0c;具体的任务包括&#xff1a; 读取wiki数据集生成下一句预测任务的数据—>主要用于_get_nsp_data_from_paragraph函数从输入paragraph生成用于下一句预测的训练样本&#xff1a;_get_nsp_data_from_paragraph生…

css常见问题处理

文章目录 1&#xff1a;禁止文字被复制粘贴1.1 Css 处理1.2 Js 处理 2&#xff1a;元素垂直水平居中2.1:方案一2.2 方案二2.3 方案三2.4 方案四2.5 方案五 1&#xff1a;禁止文字被复制粘贴 1.1 Css 处理 <div class"text">我不可以复制信息</div> <…

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

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