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. 关于 Xpath 定位

    关于 Xpath 定位 问: // 和 / 的区别 表达式 描述 nodename 选取此节点的所有子节点. / 从根节点选取. // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置. . ...

  2. IMX6Q开发板Linux-QT挂载U盘及TF卡

    本文基于:迅为-iMX6开发板Linux-QT挂载U盘及TF卡 如下图所示,qt 启动之后,在超级终端中使用命令“mknod /dev/sda1 b 8 1”创建 U盘的设备节点,如下图所示. 插入 ...

  3. Octave 常用命令

    GNU Octave 官方文档 GNU Octave Documentation(Online) GNU Octave Documentation(PDF) 安装额外的包 Installing and ...

  4. nc命令的用法

    1.什么是nc netcat(nc)是一个简单而有用的工具,可以使用tcp或者udp进行网络间读写数据,传输文件,接收发送数据,验证网络是否畅通. 2.命令行: 1) -l 用于指定nc将处于侦听模式 ...

  5. 解决一个通过 WebReference 调用 WCF 时自定义 DataContract 类参数提交的问题

    先看一下VS2013自动创建默认的IService1.vb,注意自定义的数据契约 CompositeType ' 注意: 使用上下文菜单上的“重命名”命令可以同时更改代码和配置文件中的接口名“ISer ...

  6. BCM93349DCM 手动升级 Fireware 指导

    PC:Personal Computer(这里用的Win7) CM:Cable MODEM(芯片:BCM93349DCM) 一.预置条件 1.PC上已安装TFTP Server,比如tftpd32: ...

  7. CountingSort(计数排序)原理及C++代码实现

    计数排序是需要假设输入数据的排序之一,它假设输入元素是0到k区间内的一个整数,其中k为某个整数.当k=O(n)时,计数排序的时间复杂度为θ(n). 因为不是通过比较来排序,所以它的时间复杂度可以达到θ ...

  8. Struts2加载自定义库注意事项

    新建Struts2项目,添加Struts2的jar包时,往往通过导入自定义库的方式,导入自定义库时,有个地方必须要设置,否则项目无法正常执行,如图所示: 必须要按照上述方式对自定义库进行加载!

  9. 提前窥测奥斯卡颁奖信封中的谜底  ——Rothschild预测2014奥斯卡花落谁家

     --Rothschild预测2014奥斯卡花落谁家" title="提前窥测奥斯卡颁奖信封中的谜底  --Rothschild预测2014奥斯卡花落谁家"> 编者 ...

  10. ospf实验二

    R1,R2,R3为17.1.1.0网段 1. R4先做rip #rip 1 #version 2 #undo sum.. #netwokr 14.0.0.0 实验第四条 标记tag 100 在R4上做 ...