Sentinel 控制台与 Nacos 实现配置的双向同步和持久化存储

Sentinel 控制台与 Nacos 实现配置的双向同步和持久化存储

引言

随着微服务架构的普及,服务间的调用关系变得更加复杂,流量控制和熔断机制成为保障系统稳定性的关键。Sentinel 是阿里巴巴开源的一款流量控制组件,它提供了丰富的流量控制手段以及实时监控功能。但在实际应用中,为了实现配置的动态调整和持久化,通常会结合配置中心来使用。本文将详细介绍如何利用 Nacos 作为配置中心,与 Sentinel 控制台一起,实现配置的双向同步与持久化存储。

规则管理及推送

该部分内容引自官方问答

一般来说,规则的推送有下面三种模式:

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

如果不做任何修改,Dashboard 的推送规则方式是通过 API 将规则推送至客户端并直接更新到内存中:
在这里插入图片描述

这种做法的好处是简单,无依赖;坏处是应用重启规则就会消失,仅用于简单测试,不能用于生产环境。

Pull模式

pull 模式的数据源(如本地文件、RDBMS 等)一般是可写入的。使用时需要在客户端注册数据源:将对应的读数据源注册至对应的 RuleManager,将写数据源注册至 transport 的 WritableDataSourceRegistry 中。以本地文件数据源为例:

public class FileDataSourceInit implements InitFunc {

    @Override
    public void init() throws Exception {
        String flowRulePath = "xxx";

        ReadableDataSource<String, List<FlowRule>> ds = new FileRefreshableDataSource<>(
            flowRulePath, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {})
        );
        // 将可读数据源注册至 FlowRuleManager.
        FlowRuleManager.register2Property(ds.getProperty());

        WritableDataSource<List<FlowRule>> wds = new FileWritableDataSource<>(flowRulePath, this::encodeJson);
        // 将可写数据源注册至 transport 模块的 WritableDataSourceRegistry 中.
        // 这样收到控制台推送的规则时,Sentinel 会先更新到内存,然后将规则写入到文件中.
        WritableDataSourceRegistry.registerFlowDataSource(wds);
    }

    private <T> String encodeJson(T t) {
        return JSON.toJSONString(t);
    }
}

本地文件数据源会定时轮询文件的变更,读取规则。这样我们既可以在应用本地直接修改文件来更新规则,也可以通过 Sentinel 控制台推送规则。以本地文件数据源为例,推送过程如下图所示:
在这里插入图片描述

首先 Sentinel 控制台通过 API 将规则推送至客户端并更新到内存中,接着注册的写数据源会将新的规则保存到本地的文件中。使用 pull 模式的数据源时一般不需要对 Sentinel 控制台进行改造。

这种实现方法好处是简单,不引入新的依赖,坏处是无法保证监控数据的一致性。

Push模式

生产环境下一般更常用的是 push 模式的数据源。对于 push 模式的数据源,如远程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不应由 Sentinel 客户端进行,而应该经控制台统一进行管理,直接进行推送,数据源仅负责获取配置中心推送的配置并更新到本地。因此推送规则正确做法应该是 配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel,而不是经 Sentinel 数据源推送至配置中心。这样的流程就非常清晰了:

在这里插入图片描述

1. 环境准备

在开始之前,请确保已安装以下软件:

  • Java 8 或更高版本
  • Maven 或其他构建工具
  • Nacos 服务端(版本推荐 2.3.0 或以上)
  • Sentinel 控制台(版本推荐 1.8.6)

1.1 安装 Nacos

您可以从 Nacos GitHub 仓库 下载最新的发行版,或者使用 Docker 安装 Nacos。这里以下载安装为例:

1 wget https://github.com/alibaba/nacos/releases/download/2.3.0/nacos-server-2.3.0.zip
2 unzip nacos-server-2.3.0.zip
3 cd nacos/bin
4 ./startup.sh -m standalone

如果需要持久化nacos的配置,后续出单独文章解析

1.2 安装 Sentinel 控制台

您也可以从 Sentinel GitHub 仓库 下载1.8.6版本的zip源码包
在这里插入图片描述

2. 使用 Nacos 作为 Sentinel 的数据源

2.1 项目加载

解压后利用idea开发工具打开该项目

2.2 配置 Nacos 服务器

在这里插入图片描述

编辑 application.properties 文件,添加 Nacos 服务器的相关配置:

# Sentinel 连接nacos配置
sentinel.nacos.username={usr}
sentinel.nacos.password={pwd}
sentinel.nacos.namespace={namespace}
sentinel.nacos.server-addr={ip}:{port}

2.3 配置 Sentinel 控制台

Sentinel 控制台中,通过配置面板将 Nacos 设置为数据源。这一步骤可以通过控制台的“数据源管理”功能完成。

2.3.1 修改 POM 文件

因项目的nacos作为数据源的相关文件原来在测试包内,现在需要将 sentinel-datasource-nacos 包的 scope 注释掉,以便在 Sentinel 控制台中使用 Nacos 作为数据源。

<!-- 将以下依赖的 scope 注释掉 -->
     <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
        <version>1.8.6</version>
        <scope>test</scope>
    </dependency>
2.3.2 复制 Nacos 相关类

复制test包下的 FlowRuleNacosProviderFlowRuleNacosPublisherNacosConfigNacosConfigUtils 四个类到 main 目录下的 rule 包下。

  • 初始位置:
    在这里插入图片描述
  • 目标位置:
    在这里插入图片描述
2.3.3 配置 Nacos

新增NacosPropertiesConfiguration配置类

package com.alibaba.csp.sentinel.dashboard.rule;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;


@ConfigurationProperties(prefix = "sentinel.nacos")
@Configuration
public class NacosPropertiesConfiguration {
    private String serverAddr;
    private String dataId;
    private String groupId;
    private String namespace;
    private String username;
    private String password;
	//自行补充get与set方法
}


修改 NacosConfig 类以支持自定义配置:

package com.alibaba.csp.sentinel.dashboard.rule;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigFactory;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.Properties;

/**
 * @author Eric Zhao
 * @since 1.4.0
 */
@Configuration
public class NacosConfig {

    @Bean
    public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {
        return JSON::toJSONString;
    }

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


    @Bean
    public ConfigService nacosConfigService(NacosPropertiesConfiguration nacosPropertiesConfiguration) throws Exception {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, nacosPropertiesConfiguration.getServerAddr());
        properties.put(PropertyKeyConst.NAMESPACE, nacosPropertiesConfiguration.getNamespace());
        properties.put(PropertyKeyConst.USERNAME, nacosPropertiesConfiguration.getUsername());
        properties.put(PropertyKeyConst.PASSWORD, nacosPropertiesConfiguration.getPassword());
        return ConfigFactory.createConfigService(properties);
    }

}

修改 FlowRuleNacosPublisher 确认配置文件格式为JSON

package com.alibaba.csp.sentinel.dashboard.rule;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.ConfigType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author Eric Zhao
 * @since 1.4.0
 */
@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {

    @Autowired
    private ConfigService configService;
    @Autowired
    private Converter<List<FlowRuleEntity>, String> converter;

    @Override
    public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
        AssertUtil.notEmpty(app, "app name cannot be empty");
        if (rules == null) {
            return;
        }
        configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
            NacosConfigUtil.GROUP_ID, converter.convert(rules), ConfigType.JSON.getType());
    }
}

2.4 配置 V2 版本 Controller

调用 Nacos 提供的服务层。
在这里插入图片描述

 	@Autowired
    @Qualifier("flowRuleNacosProvider")
    private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
    @Autowired
    @Qualifier("flowRuleNacosPublisher")
    private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;

3. 前端页面源码修改

3.1 添加 Nacos 接口并修改地址
  • 文件路径: src/main/webapp/resources/app/scripts/controllers/identity.js
  • 操作: 将 FlowServiceV1 改为 FlowServiceV2,将 /dashboard/flow/ 改为 /dashboard/v2/flow/
3.2 修改页面中的路由地址
  • 文件路径: src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html
  • 操作: 搜索 dashboard.flowV1 并定位到第 57 行,去掉 V1
  • 文件路径: src/main/webapp/resources/app/views/flow_v2.html
  • 操作: 注释掉回到单机页面的按钮。

4. 微服务引用

4.1 添加依赖

在微服务项目的 pom.xml 文件中添加以下依赖:

<!-- SpringCloud Alibaba Nacos -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!-- Sentinel -->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
  	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
</dependency>
<dependency>
   <groupId>com.alibaba.csp</groupId>
   <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
4.2 配置 Sentinel

在微服务的 application.ymlapplication.properties 文件中配置 Sentinel:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: ${sentinel.host}:${sentinel.port}
      datasource:
        ds1:
          nacos:
            server-addr: ${nacos.host}:${nacos.port}
            username: ${nacos.name}
            password: ${nacos.pwd}
            namespace: ${nacos.namespace}
            group-id: ${nacos.group}
            data-id: ${spring.application.name}-flow-rules
            data-type: json
            rule-type: flow

5. Nacos 中增加 Sentinel 持久化配置文件

在 Nacos 中增加一个配置文件,其文件后缀和组名需要与上面的配置相匹配。

6. 双向同步与持久化存储

一旦配置完成,Sentinel 控制台中的所有更改都会被同步到 Nacos 中,而 Nacos 中的任何更改也会被自动加载到 Sentinel 控制台。这意味着开发人员可以在 Nacos 中直接修改配置文件,而不必重新启动 Sentinel 控制台即可看到效果。

6.1 动态刷新

Nacos 中的配置发生变化时,Sentinel 控制台能够自动检测到这些变化并进行刷新。这种机制保证了配置的一致性和实时性。

6.2 持久化存储

由于所有的配置都保存在 Nacos 中,因此即使 Sentinel 控制台重启或崩溃,配置也不会丢失。这对于生产环境下的稳定性至关重要。

7. 测试效果

完成上述步骤后,您可以测试 Sentinel 控制台与 Nacos 之间的双向同步和持久化存储功能。

8. 结论

通过将 Sentinel 控制台与 Nacos 结合使用,我们可以轻松地实现配置的动态管理和持久化存储。这种方式不仅简化了配置管理流程,还提高了系统的稳定性和可维护性。对于需要频繁调整规则的大规模分布式系统来说,这是一种非常实用的解决方案。

Sentinel 控制台是一个基于 Spring Cloud 的应用,它提供了一个可视化的界面来管理和监控 Sentinel 的流控规则、降级规则、系统规则等。而 Nacos 是一个开源的注册中心和配置中心,它提供了服务注册、配置管理和服务发现等功能。将 Sentinel 控制台持久化Nacos 可以实现Sentinel 控制台配置的动态管理和版本控制。 将 Sentinel 控制台持久化Nacos,需要进行以下步骤: 1. 在 Nacos 控制台中创建一个命名空间和配置集,用来保存 Sentinel 控制台配置信息。 2. 在 Sentinel 控制台的 application.properties 配置文件中,添加以下配置: ``` # 配置 Nacos 的服务地址和命名空间 spring.cloud.nacos.config.server-addr=<Nacos 服务地址> spring.cloud.nacos.config.namespace=<Nacos 命名空间> # 配置 Sentinel 控制台配置信息 spring.cloud.sentinel.transport.dashboard=localhost:8080 management.endpoints.web.exposure.include=sentinel spring.cloud.sentinel.eager=true ``` 3. 在 Sentinel 控制台启动后,访问 http://localhost:8080/nacos/config 会自动将 Sentinel 控制台配置信息保存到 Nacos 中。 4. 在 Nacos 控制台中修改 Sentinel 控制台配置信息,可以实现Sentinel 控制台配置的动态管理和版本控制。 需要注意的是,将 Sentinel 控制台持久化Nacos 需要使用 Sentinel 控制台的 1.8.0 版本及以上,同时需要安装 Nacos配置中心服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值