Sentinel(二十五)之Sentinel Dashboard同步Apollo存储规则

转载自   Spring Cloud Alibaba基础教程:Sentinel Dashboard同步Apollo存储规则

在之前的两篇教程中我们分别介绍了如何将Sentinel的限流规则存储到Nacos和Apollo中。同时,在文末的思考中,我都指出了这两套整合方案都存在一个不足之处:不论采用什么配置中心,限流规则都只能通过Nacos界面或Apollo界面来完成修改才能得到持久化存储,而在Sentinel Dashboard中修改限流规则虽然可以生效,但是不会被持久化到配置中心。而在这两个配置中心里存储的数据是一个Json格式,当存储的规则越来越多,对该Json配置的可读性与可维护性会变的越来越差。所以,下面我们就来继续探讨这个不足之处,并给出相应的解决方案。本文以Apollo存储为例,下一篇介绍Nacos的改在示例。

问题分析

在实际操作之前,我们先通过下图了解一下之前我们所实现的限流规则持久化方案的配置数据流向图:

  • 蓝色箭头代表了限流规则由配置中心发起修改的更新路径
  • 橙色箭头代表了限流规则由Sentinel Dashboard发起修改的更新路径

从图中可以很明显的看到,Sentinel Dashboard与业务服务之间本身是可以互通获取最新限流规则的,这在没有整合配置中心来存储限流规则的时候就已经存在这样的机制。最主要的区别是:配置中心的修改都可以实时的刷新到业务服务,从而被Sentinel Dashboard读取到,但是对于这些规则的更新到达各个业务服务之后,并没有一个机制去同步到配置中心,作为配置中心的客户端也不会提供这样的逆向更新方法。

改造方案

关于如何改造,现来解读一下官方文档中关于这部分的说明:

要通过 Sentinel 控制台配置集群流控规则,需要对控制台进行改造。我们提供了相应的接口进行适配。

从 Sentinel 1.4.0 开始,我们抽取出了接口用于向远程配置中心推送规则以及拉取规则:

  • DynamicRuleProvider: 拉取规则
  • DynamicRulePublisher: 推送规则

对于集群限流的场景,由于每个集群限流规则都需要唯一的 flowId,因此我们建议所有的规则配置都通过动态规则源进行管理,并在统一的地方生成集群限流规则。

我们提供了新版的流控规则页面,可以针对应用维度推送规则,对于集群限流规则可以自动生成 flowId。用户只需实现 DynamicRuleProvider 和 DynamicRulePublisher 接口,即可实现应用维度推送(URL: /v2/flow)。

这段内容什么意思呢?简单的说就是Sentinel Dashboard通过DynamicRuleProviderDynamicRulePublisher两个接口来获取和更新应用的动态规则。默认情况下,就如上一节中Sentinel Dashboard与各业务服务之间的两个箭头,一个接口负责获取规则,一个接口负责更新规则。

所以,只需要通过这两个接口,实现对配置中心中存储规则的读写,就能实现Sentinel Dashboard中修改规则与配置中心存储同步的效果。

具体的配置数据流向图如下:

其中,绿色箭头为公共公共部分,即:不论从培中心修改,还是从Sentinel Dashboard修改都会触发的操作。这样的话,从上图的两处修改起点看,所有涉及的部分都能获取到一致的限流规则了。

代码实现

下面继续说说具体的代码实现,这里参考了Sentinel Dashboard源码中关于Apollo实现的测试用例。但是由于考虑到与Spring Cloud Alibaba的结合使用,略作修改。

第一步:修改pom.xml中的Apollo OpenAPi的依赖,将<scope>test</scope>注释掉,这样才能在主程序中使用。

<dependency><groupId>com.ctrip.framework.apollo</groupId><artifactId>apollo-openapi</artifactId><version>1.2.0</version><!--<scope>test</scope>-->
</dependency>

第二步:找到resources/app/scripts/directives/sidebar/sidebar.html中的这段代码:

<li ui-sref-active="active"><a ui-sref="dashboard.flowV1({app: entry.app})"><i class="glyphicon glyphicon-filter"></i>&nbsp;&nbsp;流控规则</a>
</li>

修改为:

<li ui-sref-active="active"><a ui-sref="dashboard.flow({app: entry.app})"><i class="glyphicon glyphicon-filter"></i>&nbsp;&nbsp;流控规则</a>
</li>

第三步:在com.alibaba.csp.sentinel.dashboard.rule包下新建一个apollo包,用来编写针对Apollo的扩展实现。

第四步:创建Apollo的配置类,定义Apollo的portal访问地址以及第三方应用访问的授权Token(通过Apollo管理员账户登录,在“开放平台授权管理”功能中创建),具体代码如下:

@Configuration
public class ApolloConfig {@Beanpublic Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {return JSON::toJSONString;}@Beanpublic Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {return s -> JSON.parseArray(s, FlowRuleEntity.class);}@Beanpublic ApolloOpenApiClient apolloOpenApiClient() {ApolloOpenApiClient client = ApolloOpenApiClient.newBuilder().withPortalUrl("https://apollo.xxx.com")  // TODO 根据实际情况修改.withToken("open api token") // TODO 根据实际情况修改.build();return client;}}

第五步:实现Apollo的配置拉取实现。

@Component("flowRuleApolloProvider")
public class FlowRuleApolloProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {@Autowiredprivate ApolloOpenApiClient apolloOpenApiClient;@Autowiredprivate Converter<String, List<FlowRuleEntity>> converter;@Value("${env:DEV}")private String env;@Overridepublic List<FlowRuleEntity> getRules(String appName) throws Exception {// flowDataId对应String flowDataId = "sentinel.flowRules";OpenNamespaceDTO openNamespaceDTO = apolloOpenApiClient.getNamespace(appName, env, "default", "application");String rules = openNamespaceDTO.getItems().stream().filter(p -> p.getKey().equals(flowDataId)).map(OpenItemDTO::getValue).findFirst().orElse("");if (StringUtil.isEmpty(rules)) {return new ArrayList<>();}return converter.convert(rules);}
}
  • getRules方法中的appName参数是Sentinel中的服务名称,这里直接通过这个名字获取Apollo配置是由于Apollo中的项目AppId与之一致,如果存在不一致的情况,则需要自己做转换。
  • 这里注入了一个env属性,主要由于我们在使用Apollo的时候,通过启动参数来控制不同环境。所以这样就能在不同环境区分不同的限流配置了。
  • 这里的flowDataId对应各个微服务应用中定义的spring.cloud.sentinel.datasource.ds.apollo.flowRulesKey配置,即:Apollo中使用了什么key来存储限流配置。
  • 其他如Cluster、Namepsace都采用了默认值:default和application,这个读者有特殊需求可以做对应的修改。

第六步:实现Apollo的配置推送实现。

@Component("flowRuleApolloPublisher")
public class FlowRuleApolloPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {@Autowiredprivate ApolloOpenApiClient apolloOpenApiClient;@Autowiredprivate Converter<List<FlowRuleEntity>, String> converter;@Value("${env:DEV}")private String env;@Overridepublic void publish(String app, List<FlowRuleEntity> rules) throws Exception {String flowDataId = "sentinel.flowRules";AssertUtil.notEmpty(app, "app name cannot be empty");if (rules == null) {return;}OpenItemDTO openItemDTO = new OpenItemDTO();openItemDTO.setKey(flowDataId);openItemDTO.setValue(converter.convert(rules));openItemDTO.setComment("modify by sentinel-dashboard");openItemDTO.setDataChangeCreatedBy("apollo");apolloOpenApiClient.createOrUpdateItem(app, env, "default", "application", openItemDTO);// Release configurationNamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO();namespaceReleaseDTO.setEmergencyPublish(true);namespaceReleaseDTO.setReleaseComment("release by sentinel-dashboard");namespaceReleaseDTO.setReleasedBy("apollo");namespaceReleaseDTO.setReleaseTitle("release by sentinel-dashboard");apolloOpenApiClient.publishNamespace(app, env, "default", "application", namespaceReleaseDTO);}
}
  • 这里的大部分内容,如:env、flowDataId、app说明与上一步中的实现一致
  • openItemDTO.setDataChangeCreatedBy("apollo");namespaceReleaseDTO.setReleasedBy("apollo");这两句需要注意一下,必须设置存在并且有权限的用户,不然会更新失败。

第七步:修改com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2DynamicRuleProviderDynamicRulePublisher注入的Bean,改为上面我们编写的针对Apollo的实现:

@Autowired
@Qualifier("flowRuleApolloProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleApolloPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;

代码示例

本文介绍内容的客户端代码,示例读者可以通过查看下面仓库中的alibaba-sentinel-dashboard-apollo项目:

  • Github:https://github.com/dyc87112/SpringCloud-Learning/
  • Gitee:https://gitee.com/didispace/SpringCloud-Learning/

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

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

相关文章

为什么选择.NETCore?

为什么选择.NETCore&#xff1f;在开展话题之前先出一张ASP.NETCore VS Node.js的性能对比图 ASP.NET Core VS node.js&#xff1a;继续正文&#xff1a;学习新的开发框架是一项巨大的投资。您需要学习如何在新框架中编写&#xff0c;构建&#xff0c;测试&#xff0c;部署…

欢乐纪中某A组赛【2019.7.10】

前言 好烦我最后写对了T1T1T1的808080分结果交错题导致T2T2T2的404040分没了T1T1T1也没拿多那些分。 话说好像ZDYZDYZDY比我还惨 成绩 这里还是按OJOJOJ上的分数排名 JJJ表示初中&#xff0c;HHH表示高中后面加的是几年级 RankRankRankPersonPersonPersonScoreScoreScoreAAA…

用C#编写Linux守护进程

如果要在Red Hat Enterprise Linux上将.NET Core进程作为后台进程运行&#xff0c;则可以创建自定义systemd单元。今天我将为.NET Core编写两个自定义系统单元的例子。一个是运行.NET Core控制台应用程序的一种类型&#xff0c;另一个是运行ASP.NET Core Web应用程序的简单类型…

AWS Lambda现已支持.NET Core 2.0

Amazon宣称.NET Core 2.0现在已经支持AWS Lambda以及无服务器应用程序了。开发者们现在可以使用C#和.NET Core 2.0来为AWS Lambda编写代码和编写运行于AWS的无服务器应用程序了。自2017年2月Amazon开始了对C#编程语言的支持&#xff0c;这使得.NET开发者能够使用.NET Core 1.0运…

Nacos(一)之简介

转载自 什么是 Nacos Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集&#xff0c;帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。 Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现…

开源纯C#工控网关+组态软件(八)表达式编译器

一、 引子监控画面的主要功能之一就是跟踪下位机变量变化&#xff0c;并将这些变化展现为动画。大部分时候&#xff0c;界面上一个图元组件的某个状态&#xff0c;与单一变量Tag绑定&#xff0c;比如电机的运行态&#xff0c;绑定一个MotorRunning信号&#xff1b;但有些时候…

g4e基础篇#6 了解Git历史记录

Git的版本历史记录采用了与传统集中式版本管理系统完全不同的方式进行组织&#xff0c;在刚开始使用Git的时候我们往往会不知所措&#xff0c;比如看到这样的历史记录。看到这个七拐八拐的图形&#xff0c;你可能完全不知道它代表了什么。其实这正是Git的特别之处&#xff0c;G…

Ray框架QA

Orleans与Akka对比&#xff0c;为什么选用Orleans&#xff1f;答: Akka对参与开发的人员要求更高一些&#xff0c;普遍是专家级别&#xff0c;Orleans框架进一步抽象了一层&#xff0c;结合C#语言特性&#xff0c;能普遍降低开发难度。下面是知乎网友的答案&#xff0c;可以参考…

Nacos(三)之架构

转载自 Nacos 架构 基本架构及概念 服务 (Service) 服务是指一个或一组软件功能&#xff08;例如特定信息的检索或一组操作的执行&#xff09;&#xff0c;其目的是不同的客户端可以为不同的目的重用&#xff08;例如通过跨进程的网络调用&#xff09;。Nacos 支持主流的服务…

ASP.NET Core Razor页面禁用防伪令牌验证

这篇短文中&#xff0c;我将向您介绍如何ASP.NET Core Razor页面中禁用防伪令牌验证。Razor页面是ASP.NET Core 2.0中增加的一个页面控制器框架&#xff0c;用于构建动态的、数据驱动的网站&#xff1b;支持跨平台开发&#xff0c;可以部署到Windows&#xff0c;Unix和Mac操作系…

ASP.NETCore的Kestrel服务器

什么是Kestrel服务器Kestrel是开源的&#xff08;GitHub提供的源代码&#xff09;&#xff0c;事件驱动的异步I / O服务器&#xff0c;用于在任何平台上托管ASP.NET应用程序。这是一个监听服务器和一个命令行界面。您将侦听服务器安装在Windows或Linux服务器上&#xff0c;并在…

Polly组件对微服务场景的价值

Polly是一个开源框架,在github上可以找到,被善友大哥收录,也是.App vNext的一员!App vNext:https://github.com/App-vNextGitHub:https://github.com/App-vNext/PollyNanoFabric是一个开源的微服务架构,也是善友大哥推荐的:https://github.com/geffzhang/NanoFabric对于NanoFab…

Nacos(七)之Spring Cloud集成

转载自 Nacos Spring Cloud 快速开始 本文主要面向 Spring Cloud 的使用者&#xff0c;通过两个示例来介绍如何使用 Nacos 来实现分布式环境下的配置管理和服务注册发现。 关于 Nacos Spring Cloud 的详细文档请参看&#xff1a;Nacos Config 和 Nacos Discovery。 通过 Nac…

.NET Core 2.1中改进的堆栈信息

. NET Core 2.1 现在具有可读的异步堆栈信息&#xff01;使得异步、迭代器和字典 ( key not found ) 中的堆栈更容易追踪&#xff01;这个大胆的主张意味着什么&#xff1f;要知道&#xff0c;为了确定调用 异步 和 迭代器方法的实际重载&#xff0c;&#xff08;这在以前&…

微软高管解读财报:努力创新云基础架构

2月1日&#xff0c;微软发布了该公司截至2017年12月31日的2018年第二财季财报&#xff08;即2017年第四季度&#xff09;。财报显示&#xff0c;微软第二财季营收为289.18亿美元&#xff0c;比上年同期的258.26亿美元增长了12%。受税改与就业法案相关的一次性费用138亿美元的影…

Nacos(九)之Dubbo 融合 Nacos 成为注册中心

转载自 Dubbo 融合 Nacos 成为注册中心 Nacos 作为 Dubbo 生态系统中重要的注册中心实现&#xff0c;本文将会介绍如何进行 Dubbo 对接 Nacos 注册中心的工作。 预备工作 请确保后台已经启动 Nacos 服务&#xff0c;可先行参考 Nacos 快速入门。 快速上手 Dubbo 融合 Nac…

在.NET Core中处理一个接口多个不同实现的依赖注入问题

前言近段时间在准备公司的技术分享&#xff0c;所以这段时间将大部分时间放在准备分享内容上去了。博客也就停了一下下。在.NET Core中处理依赖注入问题时&#xff0c;往往是定义好了一个操作规范的接口&#xff0c;会有N多个基于不同技术的实现&#xff0c;根据实际情况在项目…

Nacos(十)之Kubernetes Nacos

转载自 Kubernetes Nacos 本项目包含一个可构建的Nacos Docker Image&#xff0c;旨在利用StatefulSets在Kubernetes上部署Nacos 快速开始 Clone 项目 git clone https://github.com/nacos-group/nacos-k8s.git简单例子如果你使用简单方式快速启动,请注意这是没有使用持久化…

.net core连接MongoDB

前两天在学习MongoDB相关的知识&#xff0c;做了个小Demo&#xff0c;做的是省份下面有多少所学校&#xff0c;嗯&#xff0c;做的比较粗暴。。。连接MongoDB首先要通过Nuget添加一个MongoDB的包&#xff0c;下载此包安装完毕后开始写代码了&#xff0c;创建一个省份实体&#…

Nacos(十一)之NacosSync 介绍

转载自 NacosSync 介绍 介绍 NacosSync是一个支持多种注册中心的同步组件,基于Spring boot开发框架,数据层采用Spring Data JPA,遵循了标准的JPA访问规范,支持多种数据源存储,默认使用Hibernate实现,更加方便的支持表的自动创建更新使用了高效的事件异步驱动模型, 支持多种自…