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. django框架进阶-分页-长期维护

    ##################   分页    ####################### 分页, django有自己内置的分页,但是功能不是很强大,所以自己写一个分页, web页面数据非常 ...

  2. gene cluster|DPG|拉马克主义变异|达尔文主义变异

    生命组学 A gene cluster is part of a gene family. A gene cluster is a group of two or more genes found w ...

  3. hdu1069 Monkey and Banana LIS

    #include<cstdio> #include<iostream> #include<algorithm> #include<queue> #inc ...

  4. 关于MyBatis的运行原理(转载)

    1.获取sqlSessionFactory对象: 解析文件的每一个信息保存在Configuration中,返回包含Configuration的DefaultSqlSessionFactory: 注意: ...

  5. sshd启动故障“Failed to start OpenSSH Server daemon ”解决方法

  6. [LC] 232. Implement Queue using Stacks

    Implement the following operations of a queue using stacks. push(x) -- Push element x to the back of ...

  7. [LC] 104. Maximum Depth of Binary Tree

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  8. 2017 ACM-ICPC, Universidad Nacional de Colombia Programming Contest K - Random Numbers (dfs序 线段树+数论)

    Tamref love random numbers, but he hates recurrent relations, Tamref thinks that mainstream random g ...

  9. (警告)不要轻易删除libc.so.6,以及误删恢复

    网上有很多帖子介绍升级libc.so.6库的帖子,这里存在巨大的坑: 如: Linux/CentOS 升级C基本运行库CLIBC的注意事项(当想解决GLIBC_2.x找不到的编译问题) 里边都会有这样 ...

  10. Windows server 2008 r2下安装sqlserver2012

    在微软官网上下载sqlserver2012镜像文件:用Alcohol 120%软件进行驱动安装. 如果C盘的容量不够的话,上边的路径可以修改