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. hibernate中session.flush()

    flush()session flush在commit之前默认都会执行, 也可以手动执行,他主要做了两件事: 1) 清理缓存. 2) 执行SQL. flush: Session 按照缓存中对象属性变化 ...

  2. 29)PHP,自动加载类

    (1)作用: 类的自动加载是指,在外面的页面中,并不需要去“引入”(包含)类文件,但是程序会在需要一个类的时候就自动去“动态加载”该类. (2)什么叫做“需要一个类”?通常是这样的情况: 1,创建一个 ...

  3. 微信小程序的标签和html标签比较

    html 小程序 <div></div> <view></view> <h1><h2>....<h6> <p& ...

  4. King of the Waves

    You are organising a king of the hill tournament, the Buenos Aires Paddleboarding Competition (BAPC) ...

  5. Hypothesis Tests for One Population Mean When σ Is Known

    9.5 Hypothesis Tests for One Population Mean When σ Is Known 使用z-test前提(同使用mean distribution之前的考虑) 在 ...

  6. svn使用2(转)

    首先打开VisualSVN Server Manager,如图: 可以在窗口的右边看到版本库的一些信息,比如状态,日志,用户认证,版本库等.要建立版本库,需要右键单击左边窗口的Repositores, ...

  7. linux centos的安装及一些相关知识的整理

    相关知识点        ***网桥:主机和虚拟机之间使用"桥接"网络组网 VMware 0 ***Net适配器:把本地网中虚拟机的ip地址转换为主机的外部网络地址 ***仅主机适 ...

  8. tomcat启动不了的问题

    tomcat启动的几个问题 1.端口冲突 2.非端口冲突,需要加入配置host文件 日志文件: 解决办法:https://blog.csdn.net/u012949658/article/detail ...

  9. apache和tomcat的关系

    apache和tomcat的关系: 举个例子:apache是一辆卡车,上面可以装一些东西如html等.但是不能装水,要装水必须要有容器(桶),tomcat就是一个桶(装像JAVA这样的水),而这个桶也 ...

  10. Trie树的插入,查前缀,查单词,删前缀和删单词。

    这个Trie原先用C++就敲得很熟了,看了蓝桥杯的视频后学会把一个功能这样封装起来,以后用的时候就很爽可以直接调用了,所以就用Java写了: public class Trie { private f ...