Sentinel Client: 整合Apollo规则持久化

2024-05-24 14:48

本文主要是介绍Sentinel Client: 整合Apollo规则持久化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在前面的学习过程中,Sentinel 的规则,也就是我们之前定义的限流规则,是通过代码的方式定义好的。这是初始化时需要做的事情,Sentinel 提供了基于API的方式修改规则:

FlowRuleManager.loadRules(List<FlowRule> rules); // 修改流控规则
DegradeRuleManager.loadRules(List<DegradeRule> rules); // 修改降级规则
SystemRuleManager.loadRules(List<SystemRule> rules); // 修改系统规则
AuthorityRuleManager.loadRules(List<AuthorityRule> rules); // 修改授权规则

当我们接入了控制台后,可以通过控制台进行规则的动态修改,问题是当应用程序重启后规则信息就会恢复到初始化的阶段,也就是说后面修改的值会丢失,因为规则信息都是存储在应用的内存中。

为了解决这个问题Sentinel 提供了DataSource 扩展的功能,官方推荐通过控制台设置规则后将规则推送到统一的规则中心,客户端实现 ReadableDataSource 接口端监听规则中心实时获取变更,流程如下:

扩展的常见方式有推和拉两种模式:

  • 拉模式:客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件,甚至是 VCS 等。这样做的方式是简单,缺点是无法及时获取变更;
  • 推模式:规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Apollo、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。

今天我们主要是讲如何使用 Apollo 来配置规则进行持久化,Apollo是携程开源的配置中心,非常好用

Github地址:https://github.com/ctripcorp/apollo

在我的书中也有对Apollo使用的详细介绍,等出版了再通知大家。

首先集成需要的依赖:

<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-apollo</artifactId><version>1.4.1</version>
</dependency>

然后创建 ApolloDataSource 并将其注册至对应的 RuleManager 上即可。比如:

private static void loadRules() {// Apollo 中的应用名称,自己定义的String appId = "SampleApp";// Apollo 的地址String apolloMetaServerAddress = "http://localhost:8080";System.setProperty("app.id", appId);System.setProperty("apollo.meta", apolloMetaServerAddress);// 指定环境System.setProperty("env", "DEV");// Apollo 的命名空间String namespaceName = "application";// 限流规则的Key, 在Apollo中用此KeyString flowRuleKey = "flowRules";// 限流规则的默认值String defaultFlowRules = "[]";// 注册数据源ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ApolloDataSource<>(namespaceName,flowRuleKey, defaultFlowRules, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}

到此为止配置就结束了,详细的解释我都写了注释哈。官方文档也是这么写的,问题是如果你刚接触会一头雾水的,为什么?

你不知道在Apollo中怎么配置啊,我们讲的就是说可以用Apollo来作为存储,持久化规则,那么规则怎么配置就需要我们自己去想。

我也是通过看源码才知道怎么去配置的,带着大家一起来看源码吧!

主要就是new ApolloDataSource这里,参数都是通过这里传进去的

public ApolloDataSource(String namespaceName, String flowRulesKey, String defaultFlowRuleValue,Converter<String, T> parser) {super(parser);Preconditions.checkArgument(!Strings.isNullOrEmpty(namespaceName), "Namespace name could not be null or empty");Preconditions.checkArgument(!Strings.isNullOrEmpty(flowRulesKey), "FlowRuleKey could not be null or empty!");this.flowRulesKey = flowRulesKey;this.defaultFlowRuleValue = defaultFlowRuleValue;this.config = ConfigService.getConfig(namespaceName);initialize();RecordLog.info(String.format("Initialized rule for namespace: %s, flow rules key: %s",namespaceName, flowRulesKey));}

这边就是对传入的参数赋值,然后看下面这行:

this.config = ConfigService.getConfig(namespaceName);

这就是通过命名空间去Apollo中获取配置,获取完后就执行初始化

private void initialize() {initializeConfigChangeListener();loadAndUpdateRules();
}

initializeConfigChangeListener是初始化配置的监听器,当配置发生修改时会进入该监听器,也就是说在这个监听器里需要监听配置的修改,然后更新规则

 private void initializeConfigChangeListener() {config.addChangeListener(new ConfigChangeListener() {@Overridepublic void onChange(ConfigChangeEvent changeEvent) {ConfigChange change = changeEvent.getChange(flowRulesKey);//change is never null because the listener will only notify for this keyif (change != null) {RecordLog.info("[ApolloDataSource] Received config changes: " + change.toString());}loadAndUpdateRules();}}, Sets.newHashSet(flowRulesKey));}

loadAndUpdateRules就是更新规则的逻辑了

private void loadAndUpdateRules() {try {T newValue = loadConfig();if (newValue == null) {RecordLog.warn("[ApolloDataSource] WARN: rule config is null, you may have to check your data source");}getProperty().updateValue(newValue);} catch (Throwable ex) {RecordLog.warn("[ApolloDataSource] Error when loading rule config", ex);}}

那么配置是怎么来的呢,请看loadConfig

 @Overridepublic T loadConfig() throws Exception {return loadConfig(readSource());}public T loadConfig(S conf) throws Exception {T value = parser.convert(conf);return value;}

readSource就是获取我们配置的flowRulesKey的值,那么配置其实就是一个字符串,然后下面通过Json转换

 public String readSource() throws Exception {return config.getProperty(flowRulesKey, defaultFlowRuleValue);}

我们再返过来看看注册的代码:

 // 注册数据源ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ApolloDataSource<>(namespaceName,flowRuleKey, defaultFlowRules, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));

重点是ource -> JSON.parseObject(source, new TypeReference<List>()这行,这不就是转换成List吗,真相呼之欲出了,也就是在Apollo中配置的就是List的json格式就行。

我们配置一个试试看:

flowRules = [{"grade":1,"count":11,"resource":"HelloWorld"}]

点击保存并且发布,可以在initializeConfigChangeListener里面设置一个断点,你会发现,当发布配置之后,这边马上就会进来,然后执行其他的逻辑,到此为止整个流程结束。

欢迎加入我的知识星球,一起交流技术,免费学习猿天地的课程(http://cxytiandi.com/course)

PS:目前星球中正在星主的带领下组队学习Sentinel,等你哦!

微信扫码加入猿天地知识星球

猿天地

这篇关于Sentinel Client: 整合Apollo规则持久化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/998714

相关文章

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

SpringBoot项目整合Netty启动失败的常见错误总结

《SpringBoot项目整合Netty启动失败的常见错误总结》本文总结了SpringBoot集成Netty时常见的8类问题及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、端口冲突问题1. Tomcat与Netty端口冲突二、主线程被阻塞问题1. Netty启动阻

SpringBoot+Vue3整合SSE实现实时消息推送功能

《SpringBoot+Vue3整合SSE实现实时消息推送功能》在日常开发中,我们经常需要实现实时消息推送的功能,这篇文章将基于SpringBoot和Vue3来简单实现一个入门级的例子,下面小编就和大... 目录前言先大概介绍下SSE后端实现(SpringBoot)前端实现(vue3)1. 数据类型定义2.

SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)

《SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)》本文总结了SpringBoot项目整合Kafka启动失败的常见错误,包括Kafka服务器连接问题、序列化配置错误、依赖配置问题、... 目录一、Kafka服务器连接问题1. Kafka服务器无法连接2. 开发环境与生产环境网络不通二、序

SpringBoot整合Apache Spark实现一个简单的数据分析功能

《SpringBoot整合ApacheSpark实现一个简单的数据分析功能》ApacheSpark是一个开源的大数据处理框架,它提供了丰富的功能和API,用于分布式数据处理、数据分析和机器学习等任务... 目录第一步、添加android依赖第二步、编写配置类第三步、编写控制类启动项目并测试总结ApacheS

Spring Boot整合Redis注解实现增删改查功能(Redis注解使用)

《SpringBoot整合Redis注解实现增删改查功能(Redis注解使用)》文章介绍了如何使用SpringBoot整合Redis注解实现增删改查功能,包括配置、实体类、Repository、Se... 目录配置Redis连接定义实体类创建Repository接口增删改查操作示例插入数据查询数据删除数据更

Python之变量命名规则详解

《Python之变量命名规则详解》Python变量命名需遵守语法规范(字母开头、不使用关键字),遵循三要(自解释、明确功能)和三不要(避免缩写、语法错误、滥用下划线)原则,确保代码易读易维护... 目录1. 硬性规则2. “三要” 原则2.1. 要体现变量的 “实际作用”,拒绝 “无意义命名”2.2. 要让

深入浅出Java中的Happens-Before核心规则

《深入浅出Java中的Happens-Before核心规则》本文解析Java内存模型中的Happens-Before原则,解释其定义、核心规则及实际应用,帮助理解多线程可见性与有序性问题,掌握并发编程... 目录前言一、Happens-Before是什么?为什么需要它?1.1 从一个问题说起1.2 Haht

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

Spring Boot 整合 SSE(Server-Sent Events)实战案例(全网最全)

《SpringBoot整合SSE(Server-SentEvents)实战案例(全网最全)》本文通过实战案例讲解SpringBoot整合SSE技术,涵盖实现原理、代码配置、异常处理及前端交互,... 目录Spring Boot 整合 SSE(Server-Sent Events)1、简述SSE与其他技术的对