java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Sentinel  Nacos 规则推送与持久化

Sentinel 集成 Nacos 实现规则动态推送与持久化的过程

作者:Jinkxs

本文介绍了如何将Sentinel与Nacos集成,实现流量控制规则的动态推送和持久化存储,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

大家好!今天我们要深入探讨一个在微服务架构中非常重要的主题:使用 Sentinel 和 Nacos 实现规则的动态推送与持久化

在现代分布式系统中,流量控制、熔断降级和系统负载保护是保障服务稳定性的核心手段。阿里巴巴开源的 Sentinel 是一款功能强大的流量治理组件,它可以帮助我们轻松地实现这些关键特性。而 Nacos 作为阿里巴巴开源的动态服务发现、配置管理和服务管理平台,则为我们提供了强大的动态配置能力。

将 Sentinel 与 Nacos 结合,我们可以实现如下两大核心优势:

  1. 规则动态推送:无需重启应用,即可实时更新流控、降级、热点参数等规则。
  2. 规则持久化:将规则存储在 Nacos 中,确保即使服务重启,规则也不会丢失。

本文将带你一步步搭建这个集成方案,并提供详细的 Java 代码示例,让你能够快速上手实践。

🧩 一、什么是 Sentinel 和 Nacos?

🔍 Sentinel 是什么?

Sentinel 是阿里巴巴开源的一款面向分布式服务架构的流量治理组件。它以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助开发者保障微服务的稳定性。

Sentinel 的核心功能包括:

🌐 Nacos 是什么?

Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它提供了服务注册与发现、动态配置管理、服务元数据管理等功能。

Nacos 的主要特点包括:

🚀 二、为什么需要集成 Sentinel 和 Nacos?

想象一下,在一个复杂的微服务系统中,你可能有几十甚至上百个服务。每个服务都可能需要配置不同的流控规则、熔断规则和降级规则。如果这些规则都硬编码在代码里或者通过本地文件管理,那么维护起来会非常麻烦,尤其是在需要频繁调整规则的时候。

通过将 Sentinel 的规则存储在 Nacos 中,我们可以实现以下好处:

✅ 1. 规则的动态性

✅ 2. 规则的持久化

✅ 3. 与微服务生态的无缝集成

🛠️ 三、环境准备与依赖

在开始之前,请确保你已经准备好以下环境:

  1. JDK 8 或更高版本
  2. Maven 3.x
  3. Nacos Server(可下载 Nacos 官网 下载包)
  4. Spring Boot 项目

📦 Maven 依赖

我们需要在 pom.xml 文件中引入必要的依赖项。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>sentinel-nacos-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sentinel-nacos-demo</name>
    <description>Demo project for Sentinel with Nacos</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version> <!-- 请根据实际情况选择合适的版本 -->
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2021.0.3</spring-cloud.version> <!-- 请根据实际情况选择合适的版本 -->
        <sentinel.version>1.8.6</sentinel.version> <!-- 请根据实际情况选择合适的版本 -->
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Sentinel 核心依赖 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-core</artifactId>
            <version>${sentinel.version}</version>
        </dependency>
        <!-- Sentinel Spring Cloud Gateway 集成 (如果需要) -->
        <!--
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
            <version>${sentinel.version}</version>
        </dependency>
        -->
        <!-- Sentinel Spring WebFlux 集成 (如果需要) -->
        <!--
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-spring-webflux-adapter</artifactId>
            <version>${sentinel.version}</version>
        </dependency>
        -->
        <!-- Sentinel 注解支持 (用于 @SentinelResource 等注解) -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-annotation-aspectj</artifactId>
            <version>${sentinel.version}</version>
        </dependency>
        <!-- Sentinel Nacos 扩展 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
            <version>${sentinel.version}</version>
        </dependency>
        <!-- Spring Cloud Alibaba Nacos Discovery (如果需要服务发现) -->
        <!--
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2021.0.4.0</version>
        </dependency>
        -->
        <!-- Spring Cloud Alibaba Nacos Config (如果需要配置中心) -->
        <!--
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2021.0.4.0</version>
        </dependency>
        -->
        <!-- 如果你的项目是 Spring Cloud 项目,且使用了 Spring Cloud LoadBalancer,可能需要这个依赖 -->
        <!--
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>
        -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

注意点:

🧪 四、启动 Nacos Server

在开始编码之前,你需要先启动 Nacos Server。

  1. 下载 Nacos Server:前往 Nacos GitHub Releases 页面,下载适合你操作系统的版本。
  2. 解压下载的压缩包。
  3. 进入解压后的目录,执行启动命令:
    • Windows: startup.cmd
    • Linux/Mac: sh startup.sh
  4. 默认情况下,Nacos 会在 8848 端口运行。打开浏览器访问 http://localhost:8848/nacos,输入默认账号密码(通常是 nacos/nacos),你应该能看到 Nacos 的管理界面。

📝 五、编写代码示例

我们将创建一个简单的 Spring Boot 应用,并演示如何使用 Sentinel + Nacos 实现规则的动态推送与持久化。

📁 1. 创建 Controller

首先,创建一个控制器来暴露一些接口,并使用 Sentinel 的 @SentinelResource 注解来定义资源。

package com.example.sentinel.nacos.demo.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
    // 定义资源名称为 "demoResource"
    @SentinelResource(value = "demoResource", blockHandler = "handleBlockException")
    @GetMapping("/demo")
    public String demo(@RequestParam(required = false) String name) {
        if (name == null || name.isEmpty()) {
            name = "World";
        }
        return "Hello, " + name + "!";
    }
    // 当触发限流或降级时,会调用此方法
    public String handleBlockException(String name, BlockException ex) {
        System.err.println("Block exception occurred: " + ex.getClass().getSimpleName());
        return "Blocked by Sentinel! Reason: " + ex.getClass().getSimpleName();
    }
}

⚙️ 2. 配置 Nacos 数据源

为了使 Sentinel 能够从 Nacos 获取规则,我们需要在应用启动时初始化 Nacos 数据源。这通常在 main 方法或 @PostConstruct 方法中完成。

📄 application.yml

server:
  port: 8080
spring:
  application:
    name: sentinel-nacos-demo # 应用名称,用于 Nacos 中区分不同的配置
# Sentinel 配置
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 # Sentinel 控制台地址 (可选)
        port: 8080 # Sentinel 客户端向 Dashboard 发送心跳的端口 (可选)
      # 指定规则数据源为 Nacos
      datasource:
        # 定义第一个数据源 (流控规则)
        flow:
          nacos:
            server-addr: localhost:8848 # Nacos 地址
            group-id: SENTINEL_GROUP # Nacos 中的 Group ID
            data-id: ${spring.application.name}-flow.json # Nacos 中的 Data ID
            rule-type: flow # 规则类型 (flow: 流控, degrade: 熔断, system: 系统保护, authority: 授权)
        # 定义第二个数据源 (熔断规则)
        degrade:
          nacos:
            server-addr: localhost:8848
            group-id: SENTINEL_GROUP
            data-id: ${spring.application.name}-degrade.json
            rule-type: degrade
        # 定义第三个数据源 (热点参数规则)
        param-flow:
          nacos:
            server-addr: localhost:8848
            group-id: SENTINEL_GROUP
            data-id: ${spring.application.name}-param-flow.json
            rule-type: param-flow
        # 定义第四个数据源 (系统规则)
        system:
          nacos:
            server-addr: localhost:8848
            group-id: SENTINEL_GROUP
            data-id: ${spring.application.name}-system.json
            rule-type: system
        # 定义第五个数据源 (授权规则)
        authority:
          nacos:
            server-addr: localhost:8848
            group-id: SENTINEL_GROUP
            data-id: ${spring.application.name}-authority.json
            rule-type: authority
management:
  endpoints:
    web:
      exposure:
        include: '*'

说明:

🧠 初始化 Nacos 数据源 (可选 - 通过 Java 代码)

虽然上面的 YAML 配置已经足够让 Sentinel 自动加载 Nacos 规则,但如果你希望更细粒度地控制初始化过程,或者在某些特殊场景下需要手动指定,可以使用 Java 代码来初始化。

🧩 创建配置类

package com.example.sentinel.nacos.demo.config;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.List;
@Configuration
public class SentinelConfig {
    private static final Logger logger = LoggerFactory.getLogger(SentinelConfig.class);
    @Value("${spring.cloud.sentinel.datasource.flow.nacos.server-addr}")
    private String serverAddr;
    @Value("${spring.cloud.sentinel.datasource.flow.nacos.group-id}")
    private String groupId;
    @Value("${spring.cloud.sentinel.datasource.flow.nacos.data-id}")
    private String dataId;
    @PostConstruct
    public void initFlowRules() {
        ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(serverAddr, groupId, dataId,
                new Converter<String, List<FlowRule>>() {
                    @Override
                    public List<FlowRule> convert(String source) {
                        logger.info("Received flow rules from Nacos: {}", source);
                        return JSON.parseObject(source, new TypeReference<List<FlowRule>>() {});
                    }
                });
        FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
        logger.info("Flow rules loaded from Nacos successfully.");
    }
    // 可以类似地为其他规则类型(如 DegradeRule, SystemRule, AuthorityRule, ParamFlowRule)添加初始化逻辑
    // 示例:添加熔断规则初始化
    /*
    @Bean
    public ReadableDataSource<String, List<DegradeRule>> degradeRuleDataSource() {
        return new NacosDataSource<>(serverAddr, groupId, "sentinel-nacos-demo-degrade.json",
                source -> JSON.parseObject(source, new TypeReference<List<DegradeRule>>() {}));
    }
    */
}

这个配置类的作用是在应用启动后,通过 @PostConstruct 注解的方法,手动初始化一个 NacosDataSource 来监听 Nacos 中指定的 data-id 对应的配置,并将其转换为 FlowRule 对象注入到 Sentinel 的规则管理器中。

注意: 使用 @PostConstruct 的方式与 YAML 配置的方式是互补的,YAML 配置会自动处理大部分情况,而 Java 代码方式则提供了更多的灵活性。

🧪 六、测试流程

🚀 1. 启动应用

确保你的 Nacos Server 正在运行,然后启动你的 Spring Boot 应用。

🧪 2. 访问接口

访问你的应用接口,例如:

http://localhost:8080/demo?name=Test

此时,由于没有在 Nacos 中设置任何规则,接口应该能正常返回结果。

🧾 3. 在 Nacos 控制台添加规则

  1. 打开浏览器,访问 Nacos 控制台 http://localhost:8848/nacos
  2. 登录后,在左侧导航栏点击 配置管理 > 配置列表
  3. 点击 + 创建配置
  4. 填写配置信息:
    • Data ID: sentinel-nacos-demo-flow.json (对应 YAML 配置中的 data-id
    • Group: SENTINEL_GROUP (对应 YAML 配置中的 group-id
    • 配置格式: JSON
    • 配置内容: 添加如下流控规则 JSON 内容:
      [
        {
          "resource": "demoResource",
          "limitApp": "default",
          "count": 1,
          "grade": 1,
          "strategy": 0,
          "controlBehavior": 0,
          "clusterMode": false
        }
      ]
      • resource: 资源名称,与 @SentinelResource 注解中的 value 一致。
      • count: 限流阈值。
      • grade: 限流阈值类型,1 表示 QPS。
      • strategy: 调用关系限流策略,0 表示直接。
      • controlBehavior: 流控效果,0 表示直接拒绝。
      • clusterMode: 是否集群限流。
    • 点击 发布
  5. 保存后,刷新你的应用页面(或者再次调用接口)。
  6. 第二次及之后的请求,应该会因为触发了限流规则而被拦截,返回 Blocked by Sentinel! 的提示信息。

🔄 4. 动态修改规则

  1. 在 Nacos 控制台找到刚才创建的 sentinel-nacos-demo-flow.json 配置。
  2. 点击 编辑
  3. 修改 count 字段,例如改为 5
  4. 点击 发布
  5. 再次访问接口,你会发现规则已经被更新,现在可以承受更高的 QPS。

📊 5. 查看 Sentinel 控制台 (可选)

如果你在 application.yml 中配置了 dashboard 地址,你可以访问 Sentinel 控制台 (http://localhost:8080) 来查看实时监控信息和规则状态。

📈 七、规则类型详解

Sentinel 支持多种规则类型,我们已经在前面的配置中提到了其中几种。让我们详细了解一下它们:

📉 流控规则 (Flow Rule)

这是最常用的规则类型,用于控制资源的访问速率。

📋 主要字段说明:

字段类型描述
resourceString资源名称,与 @SentinelResource 中的 value 一致。
limitAppString限流的应用名,默认 default
countdouble限流阈值。
gradeint限流阈值类型,1 代表 QPS,0 代表线程数。
strategyint调用关系限流策略:0 直接、1 关联、2 链路。
controlBehaviorint流控效果:0 直接拒绝、1 Warm Up、2 匀速排队。
clusterModeboolean是否集群限流。

🧪 示例 JSON:

[
  {
    "resource": "demoResource",
    "limitApp": "default",
    "count": 1,
    "grade": 1,
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  }
]

🧨 熔断降级规则 (Degrade Rule)

用于在服务出现不稳定或错误率过高时,自动进行熔断,一段时间后恢复。

📋 主要字段说明:

字段类型描述
resourceString资源名称。
gradeint熔断策略:0 RT(平均响应时间)、1 异常比例、2 异常数。
countdouble熔断阈值。
timeWindowint熔断时长(秒)。
minRequestAmountint最小请求数。
statIntervalMsint统计窗口时间(毫秒)。
slowRatioThresholddouble慢调用比例阈值(仅 grade=0 时有效)。
maxAllowedRtMslong最大允许 RT(仅 grade=0 时有效)。

🧪 示例 JSON:

[
  {
    "resource": "demoResource",
    "grade": 1,
    "count": 0.1,
    "timeWindow": 10,
    "minRequestAmount": 10,
    "statIntervalMs": 1000
  }
]

⚖️ 系统规则 (System Rule)

从系统整体负荷角度进行保护,防止系统过载。

📋 主要字段说明:

字段类型描述
modeint系统保护模式:0 负载、1 CPU 使用率、2 平均响应时间、3 并发线程数、4 入口 QPS、5 出口 QPS。
thresholddouble阈值。

🧪 示例 JSON:

[
  {
    "mode": 1,
    "threshold": 0.7
  }
]

🔍 热点参数规则 (Param Flow Rule)

针对带有参数的资源进行限流,例如根据用户 ID 或商品 ID 限流。

📋 主要字段说明:

字段类型描述
resourceString资源名称。
limitAppString限流的应用名。
countdouble限流阈值。
gradeint限流阈值类型,1 代表 QPS。
paramIdxint参数索引。
controlBehaviorint流控效果。
clusterModeboolean是否集群限流。

🧪 示例 JSON:

[
  {
    "resource": "demoResource",
    "limitApp": "default",
    "count": 1,
    "grade": 1,
    "paramIdx": 0,
    "controlBehavior": 0,
    "clusterMode": false
  }
]

🛡️ 授权规则 (Authority Rule)

控制不同来源的访问权限。

📋 主要字段说明:

字段类型描述
resourceString资源名称。
limitAppString限制的应用名。
strategyint策略:0 白名单、1 黑名单。

🧪 示例 JSON:

[
  {
    "resource": "demoResource",
    "limitApp": "default",
    "strategy": 0
  }
]

📊 八、使用 Mermaid 图表展示集成流程

下面是一个使用 Mermaid 图表展示 Sentinel 与 Nacos 集成工作流程的示意图。

渲染错误: Mermaid 渲染失败: Parse error on line 12: ...[Sentinel Dashboard (Optional)] K -- -----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'PS'

这个图表展示了整个流程:

  1. Spring Boot 应用 启动后,通过 Sentinel 客户端与 Nacos 进行交互。
  2. Sentinel 客户端 会根据配置从 Nacos Server 中读取各种类型的规则(流控、熔断、系统、热点参数、授权)。
  3. Nacos Server 提供了统一的配置管理入口,所有的规则都存储在这里。
  4. Sentinel Dashboard (如果配置了) 可以用来查看实时的监控数据和规则状态。

📚 九、总结与展望

通过本文的学习,我们成功地将 Sentinel 与 Nacos 集成在一起,实现了规则的动态推送与持久化。这种方式不仅提升了系统的可维护性和可扩展性,也为微服务架构下的流量治理提供了强有力的支持。

✅ 本文亮点回顾

🚀 未来拓展方向

希望这篇文章能帮助你更好地理解和应用 Sentinel 与 Nacos 的集成方案。如果你有任何问题或建议,欢迎在评论区留言交流!😊

参考链接:

到此这篇关于Sentinel 集成 Nacos 实现规则动态推送与持久化的过程的文章就介绍到这了,更多相关Sentinel Nacos 规则推送与持久化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文