Sentinel基于Apollo的持久化改造

sentinel默认是将用户在dashboard中编辑过的流控信息保存在内存中,所以在重启后,所有之前配置过的流控规则也就不见了。但是sentinel给用户提供了可扩展的接口,用户可以根据自己熟悉的持久化引擎来做一定的相应的改造(apollo、nacos、zookeeper)。这里首先要了解下sentinel的规则管理和推送方式

规则管理和推送

一般来说,规则的管理和推送有以下三种方式:

推送模式 说明 优点 缺点
默认模式 API 将规则推送至客户端并直接更新到内存中,扩展写数据源 简单,无任何依赖 不保证一致性;规则保存在内存中,重启即消失。严重不建议用于生产环境
pull 模式 扩展写数据源(WritableDataSource), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件(数据库保存) 等 简单,无任何依赖;规则持久化 不保证一致性;实时性不保证,拉取过于频繁也可能会有性能问题。
push 模式 扩展读数据源(ReadableDataSource),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用 push 模式的数据源。 规则持久化;一致性;快速 引入第三方依赖

所以简单的归纳来说,sentinel(基于push)的工作原理是:

  1. 通过dashboard来配置相关的流控信息。
  2. 配置好后的规则信息通过扩展数据源推送到与之连接到客户端。
  3. 客户端在启动的过程中读取这些扩展数据源的相关规则信息,并将它们保存到内存当中。(如果客户端在运行的过程当中,规则发生变动,那么数据源会实时推送已发生变动的规则信息到正在运行的客户端内存当中)。
  4. 有请求过来的时候,客户端会读取内存中的规则信息,来判断是否做限流操作。

对数据持久化的扩展

接口描述

sentinel提供了可扩展的读写接口,在重写这块逻辑的时候,只要重新实现这两个接口就好。

Provider

Publisher

Apollo操作的封装。

不管用zk、nacos还是apollo,我们要做的就是在数据变动的时候,给这些引擎推送相关信息来驱动这些引擎去做操作。所以,可以把这些操作都抽象出来。以AbstractRuleApolloProvider为例。这个抽象类的作用有:

  1. 启动的时候初始化apollo环境。

    @Autowired
    private ApolloOpenApiClient apolloOpenApiClient;
    @Value("${auth.apollo.appId}")
    private String appid;
    private String env;
    private String clusterName;
    private String namespaceName; @PostConstruct
    public void init() {
    env = System.getProperty("env", ApolloEnvConst.APOLLO_ENV_DEV);
    clusterName = System.getProperty("cluster", ApolloEnvConst.APOLLO_DEFAULT_CLUSTER_NAME);
    namespaceName = System.getProperty("namespace", ApolloEnvConst.APOLLO_DEFAULT_NAMESPACE); }
  2. 封装对apollo通用的增删改查的方法。

     /**
    * 获取配置
    *
    * @param app
    * @return
    */
    public String getRulesByApollo(String app, String ruleType) {
    String flowDataId = getRuleType(app, ruleType);
    OpenNamespaceDTO openNamespaceDTO = apolloOpenApiClient.getNamespace(appid, env, clusterName, namespaceName);
    return openNamespaceDTO
    .getItems()
    .stream()
    .filter(p -> p.getKey().equals(flowDataId))
    .map(OpenItemDTO::getValue)
    .findFirst()
    .orElse("");
    } /**
    * 新增修改配置
    *
    * @param app
    * @param rules
    */
    public void publish2Apollo(String app, String ruleType, String rules) {
    // Increase the configuration
    String flowDataId = getRuleType(app, ruleType);
    OpenItemDTO openItemDTO = new OpenItemDTO();
    openItemDTO.setKey(flowDataId);
    openItemDTO.setValue(rules);
    openItemDTO.setComment("Program auto-join");
    openItemDTO.setDataChangeCreatedBy("apollo");
    apolloOpenApiClient.createOrUpdateItem(appid, env, clusterName, namespaceName, openItemDTO); // Release configuration
    NamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO();
    namespaceReleaseDTO.setEmergencyPublish(true);
    namespaceReleaseDTO.setReleaseComment("Modify or add configurations");
    namespaceReleaseDTO.setReleasedBy("apollo");
    namespaceReleaseDTO.setReleaseTitle("Modify or add configurations");
    apolloOpenApiClient.publishNamespace(appid, env, clusterName, namespaceName, namespaceReleaseDTO);
    }
  3. apollo数据序列化(按实际情况传递相应的实体)

    @Bean
    public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {
    return JSON::toJSONString;
    } @Bean
    public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
    return s -> JSON.parseArray(s, FlowRuleEntity.class);
    }

规则保存与推送

以降级(Degrade)为例

获取规则信息
@Component("degradeRuleApolloProvider")
public class DegradeRuleApolloProvider extends AbstractRuleApolloProvider implements DynamicRuleProvider<List<DegradeRuleEntity>> {
@Autowired
private Converter<String, List<DegradeRuleEntity>> converter; @Override
public List<DegradeRuleEntity> getRules(String app) throws Exception { String rules = super.getRulesByApollo(app, DEGRADE); if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);
} }
获取、推送规则信息
@Component("degradeRuleApolloPublisher")
public class DegradeRuleApolloPublisher extends AbstractRuleApolloProvider implements DynamicRulePublisher<List<DegradeRuleEntity>> {
@Autowired
private Converter<List<DegradeRuleEntity>, String> converter; @Override
public void publish(String app, List<DegradeRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
super.publish2Apollo(app, DEGRADE, converter.convert(rules));
} }

控制层改造

@Autowired
@Qualifier("sentinelApolloApiImpl")
private SentinelPersistenceApiService sentinelApiClient;

Sentinel基于Apollo的持久化改造的更多相关文章

  1. 阿里Sentinel控制台源码修改-对接Apollo规则持久化

    改造背景 前面我们讲解了如何对接Apollo来持久化限流的规则,对接后可以直接通过Apollo的后台进行规则的修改,推送到各个客户端实时生效. 但还有一个问题就是Sentinel控制台没有对接Apol ...

  2. 【Sentinel】sentinel 集成 apollo 最佳实践

    [Sentinel]sentinel 集成 apollo 最佳实践 前言   在 sentinel 的控制台设置的规则信息默认都是存在内存当中的.所以无论你是重启了 sentinel 的客户端还是 s ...

  3. Spring Cloud Alibaba基础教程:Sentinel使用Apollo存储规则

    上一篇我们介绍了如何通过Nacos的配置功能来存储限流规则.Apollo是国内用户非常多的配置中心,所以,今天我们继续说说Spring Cloud Alibaba Sentinel中如何将流控规则存储 ...

  4. Atitit.升级软件的稳定性---基于数据库实现持久化 循环队列 循环队列

    Atitit.升级软件的稳定性---基于数据库实现持久化  循环队列 环形队列 1. 前言::选型(马) 1 2. 实现java.util.queue接口 1 3. 当前指针的2个实现方式 1 1.1 ...

  5. 基于Apollo实现.NET Core微服务统一配置(测试环境-单机)

    一.前言 注:此篇只是为测试环境下的快速入门.后续会给大家带来生产环境下得实战开发. 具体的大家可以去看官方推荐.非常的简单明了.以下介绍引用官方内容: Apollo(阿波罗)是携程框架部门研发的分布 ...

  6. 跟我学SpringCloud | 第十七篇:服务网关Zuul基于Apollo动态路由

    目录 SpringCloud系列教程 | 第十七篇:服务网关Zuul基于Apollo动态路由 Apollo概述 Apollo相比于Spring Cloud Config优势 工程实战 示例代码 Spr ...

  7. scrapy框架基于管道的持久化存储

    scrapy框架的使用 基于管道的持久化存储的编码流程 在爬虫文件中数据解析 将解析到的数据封装到一个叫做Item类型的对象 将item类型的对象提交给管道 管道负责调用process_item的方法 ...

  8. Sentinel Client: 整合Apollo规则持久化

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

  9. sentinel控制台监控数据持久化【InfluxDB】

    根据官方wiki文档,sentinel控制台的实时监控数据,默认仅存储 5 分钟以内的数据.如需持久化,需要定制实现相关接口. https://github.com/alibaba/Sentinel/ ...

随机推荐

  1. Matlab高级教程_第二篇:Matlab相见恨晚的模块_02_并行运算-利用GPU并行执行MATLAB程序

    1 MATLAB原文: 如果所有你想使用的函数支持GPU,你能够使用gpuArray把输入的数据传输到GPU,也能够唤起gather命令把传输值GPU的数据回收. 2 通过gpuDevice命令观察当 ...

  2. 传输层TCP和UDP

    TCP协议        传输控制协议        TCP是面向连接.可靠的进程到进程通信的协议        TCP提供全双工工服务,即数据可在同一时间双向传输        三次握手:      ...

  3. 感觉自己out了

    看了公司混乱而落后的框架,想自己开发一个. 无意中到开源网站看到,开源的控件已经非常多了,基本上说应有尽有. 感叹这个知识大爆炸的年代. 自己现在是坐在井底的蛤蟆?

  4. Linux_新建用户

    目录 1.新增用户 2.增加密码 新增用户:cn 进入root 输入新建命令 cn就是我们的新的用户名,也可以换成其他的 sudo useradd cn 接下来发现没有反应,是正常的,如图 查看是否新 ...

  5. Windows CMD 终端使用代理

    Windows 终端使用代理 # 使用 http 类型代理 set http_proxy=http://127.0.0.1:8484 set https_proxy=http://127.0.0.1: ...

  6. python语法基础-基础-赋值与深浅拷贝

    ##################################### 预备知识一——python的变量及其存储 在详细的了解python中赋值.copy和deepcopy之前,我们还是要花一点时 ...

  7. python运行报错——注释报错

    本人是IT行业的,从事软件测试,还是个菜鸟.希望大神们多多关照~ 首先,开通这个博客的目的: 1)通常我容易犯一些低级的错误,而且在网上找到解决方法,解决之后时间长了又不记得: 2)想和有共同兴趣的人 ...

  8. JDK源码看Java域名解析

    前言 在互联网中通信需要借助 IP 地址来定位到主机,而 IP 地址由很多数字组成,对于人类来说记住某些组合数字很困难,于是,为了方便大家记住某地址而引入主机名和域名. 早期的网络中的机器数量很少,能 ...

  9. DOCKER中centos7的中文支持

    直接编写看下能否改变成识别中文字体 写到你的~/.bashrc里吧,然后重启终端(我写的是英文的啊,改成你要的) export LC_ALL=en_US.UTF-8 export LANGUAGE=e ...

  10. 10X genomics|cell base|in-vivo based|model organisms|SBI|

    生命组学-药物基因组学 精准医学的内容有个人全基因组测序,移动可穿戴设备,它可以实时监测,深度学习模型预测疾病,对疾病预测做到有效.安全和可控. 药物基因组学就是研究疾病.化合物和靶点之间的关系,关键 ...