springboot sentinel 制作starter和nacos配置规则 代码实现-分布式/微服务流量控制

本文详细介绍了如何在SpringBoot项目中集成Sentinel控制台,使用Nacos作为配置中心和注册中心,以及如何定义和初始化Sentinel规则。作者提供了自定义配置、启动加载规则的步骤,并分享了配置类和启动初始化代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

sentinel控制台安装

下载地址:https://github.com/alibaba/Sentinel/releases

本次版本:1.8.6
上一篇文章已介绍

目标

我们先说目标,为各位看官节省不匹配的时间
0、使用sentinel流控中心
1、使用nacos做配置中心
2、使用nacos做注册中心
3、微服务模块化
4、使用dubbo作为服务管理
5、使用springboot做脚手架

本次,制作springboot sentinel starter
当然,如果用springcloudalibaba-sentinel是一样的效果,我门在这只是单纯的使用springboot

实现代码地址

https://github.com/OrderDong/microservice-boot
分支:microservice-boot-1.0.5-sentinel

microservice-boot-middle-sentinel-starter
验证:microservice-boot-plat
在这里插入图片描述

版本说明

Dubbo :3.1.0
Springboot:2.3.1.RELEASE
sentinel:1.8.6
Nacos-config:0.2.10

制作实现

先定义yaml可识别的sentinel配置

        <!--自定义yml需要引入的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>

新建元数据JSON格式文件

• 在resource文件夹下新建META-INF文件夹
• 在META-INF文件夹下新建spring-configuration-metadata.json文件
{
  "groups": [
    {
      "name": "lwd.sentinel.dashboard",
      "type": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelServerConfigurationProperties",
      "sourceType": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelServerConfigurationProperties"
    },
    {
      "name": "lwd.sentinel.api",
      "type": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelApiConfigurationProperties",
      "sourceType": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelApiConfigurationProperties"
    }
  ],
  "properties": [
    {
      "name": "lwd.sentinel.dashboard.name",
      "type": "java.lang.String",
      "sourceType": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelServerConfigurationProperties",
      "defaultValue": "${spring.application.name}",
      "description": "sentinel控制台名称"
    },
    {
      "name": "lwd.sentinel.dashboard.server",
      "type": "java.lang.String",
      "sourceType": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelServerConfigurationProperties",
      "defaultValue": "localhost:8080",
      "description": "sentinel控制台地址"
    },
    {
      "name": "lwd.sentinel.api.addr",
      "type": "java.lang.String",
      "sourceType": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelApiConfigurationProperties",
      "description": "sentinel api地址",
      "defaultValue": "localhost:8719"
    }
  ]
}

json格式说明

groups:里面的内容是自定义配置项的父节点,有多少个父节点就配置多少个groups.

group里的name是配置yml的父节点名字

group里的type、sourceType是一样的,对应的都是整个配置项对应的配置类的去全路径

properties:里面的内容是每个父节点下具体的子节点项,就是yml文件里具体设置值的地方

properties里的name是配置yml的子节点名字

properties里的type,是子节点对应配置类里的属性的数据类型,如java.lang.String等

prooerties里的description是对该节点配置项的描述

properties里的defaultValue是该节点不配置时的默认值

properties里的sourceType对应的配置类的全路径

新增配置类

package org.lwd.microservice.boot.middle.sentinel.config;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * sentinel API接口地址
 *
 * @author weidong
 * @version V1.0.0
 * @since 2023/7/20
 */
@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "lwd.sentinel.api")
public class LwdSentinelApiConfigurationProperties {
    private String addr;
}

package org.lwd.microservice.boot.middle.sentinel.config;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 控制台配置
 *
 * @author weidong
 * @version V1.0.0
 * @since 2023/7/20
 */
@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "lwd.sentinel.dashboard")
public class LwdSentinelServerConfigurationProperties {
    private String name;
    private String server;
}

配置sentinel starter

• 在resource文件夹下新建META-INF文件夹
• 在META-INF文件夹下新建spring.factories文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.lwd.microservice.boot.middle.sentinel.MicroSentinelAutoConfiguration

实现类

package org.lwd.microservice.boot.middle.sentinel;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * 操作sentinel自动装配
 *
 * @author lwd
 * @since 2023/6/10
 */
@Slf4j
@ComponentScan(basePackages = "org.lwd.microservice.boot.middle.sentinel.config")
@Configuration
public class MicroSentinelAutoConfiguration {
    public MicroSentinelAutoConfiguration() {
        log.info("sentinel组件装配完成...");
    }

}

sentinel规则定义和初始化

我们在这只是定义了连接sentinel的参数,规则参数也可以这么定义,然后按照这种逻辑去加载

sentinel规则

package org.lwd.microservice.boot.middle.sentinel.rule;

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.CircuitBreakerStrategy;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 资源控制规则---内存模式
 * @author weidong
 * @version V1.0.0
 * @since 2023/7/17
 */
//@Configuration
public class SentinelRule {

    public static void initSentinelRule(){
        initFlowQpsRule();
        initDegradeRule();
        initSystemProtectionRule();
    }

    /**
     * 流量控制规则
     *
     * Field        说明                          默认值
     * resource     资源名,资源名是限流规则的作用对象
     * count        限流阈值
     * grade        限流阈值类型,QPS 或线程数模式       QPS 模式
     * limitApp     流控针对的调用来源               default,代表不区分调用来源
     * strategy     调用关系限流策略:直接、链路、关联   根据资源本身(直接)
     * controlBehavior  流控效果(直接拒绝 / 排队等待 / 慢启动模式),不支持按调用关系限流     直接拒绝
     */
//    @PostConstruct
    private static void initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule flowRule = new FlowRule();
        flowRule.setResource("sayHello");
        // Set max qps to 20
        flowRule.setCount(5);
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        flowRule.setLimitApp("default");
        rules.add(flowRule);
        FlowRuleManager.loadRules(rules);
    }

    /**
     * 熔断降级规则
     *
     * Field        说明                                                                                  默认值
     * resource     资源名,即规则的作用对象
     * grade        熔断策略,支持慢调用比例/异常比例/异常数策略                                                 慢调用比例
     * count        慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
     * timeWindow   熔断时长,单位为 s
     * minRequestAmount 熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入)            5
     * statIntervalMs   统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入)                              1000 ms
     * slowRatioThreshold   慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)
     */
    private static void initDegradeRule() {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule("circuitBreaker")
        .setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType())
        .setCount(0.1) // Threshold is 70% error ratio
        .setMinRequestAmount(5)
        .setStatIntervalMs(5000) // 5s
        .setTimeWindow(20);
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }

    /**
     * 系统保护规则 (SystemRule)
     * Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,
     * 通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
     *
     * Field                说明                              默认值
     * highestSystemLoad    load1 触发值,用于触发自适应控制阶段   -1 (不生效)
     * avgRt                所有入口流量的平均响应时间               -1 (不生效)
     * maxThread            入口流量的最大并发数                  -1 (不生效)
     * qps                  所有入口资源的 QPS                 -1 (不生效)
     * highestCpuUsage      当前系统的 CPU 使用率(0.0-1.0)      -1 (不生效)
     */
    private static void initSystemProtectionRule() {
        List<SystemRule> rules = new ArrayList<>();
        SystemRule rule = new SystemRule();
        rule.setHighestSystemLoad(10);
        rules.add(rule);
        SystemRuleManager.loadRules(rules);
    }

    /**
     * 来源访问控制(黑白名单)
     *
     * 我们需要根据调用方来限制资源是否通过,这时候可以使用 Sentinel 的黑白名单控制的功能。
     * 黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;
     * 若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
     *
     * 调用方信息通过 ContextUtil.enter(resourceName, origin) 方法中的 origin 参数传入。
     *
     * 黑白名单规则(AuthorityRule)非常简单,主要有以下配置项:
     *
     * resource:资源名,即限流规则的作用对象
     * limitApp:对应的黑名单/白名单,不同 origin 用 , 分隔,如 appA,appB
     * strategy:限制模式,AUTHORITY_WHITE 为白名单模式,AUTHORITY_BLACK 为黑名单模式,默认为白名单模式
     *
     */
    private static void initAuthorityRule(){
        AuthorityRule rule = new AuthorityRule();
        rule.setResource("test");
        rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
        rule.setLimitApp("appA,appB");
        AuthorityRuleManager.loadRules(Collections.singletonList(rule));
    }



}

sentinel初始化启动和加载规则


package org.lwd.microservice.boot.middle.sentinel.init;

import com.alibaba.csp.sentinel.init.InitExecutor;
import org.lwd.microservice.boot.middle.sentinel.rule.SentinelRule;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * sentinel starter 初始化
 *
 * @author weidong
 * @version V1.0.0
 * @since 2023/7/21
 */

public class LwdSentinelInit {

    public static void sentinelInitExecutor(ConfigurableApplicationContext context) {
        // 连接到控制台,与sentinel控制台通信

        //方式一:通过环境变量获取
        //System.setProperty("project.name", context.getEnvironment().getProperty("spring.application.name", "sentinel"));
        System.setProperty("csp.sentinel.dashboard.server", context.getEnvironment().getProperty("lwd.sentinel.dashboard.server", "1"));
        System.setProperty("csp.sentinel.api.port", context.getEnvironment().getProperty("lwd.sentinel.api.addr", "1"));
        //System.setProperty("sentinel.dashboard.app.hideAppNoMachineMillis", "60000");

        //方式二:手动设置
        //dashboard 地址
        //System.setProperty("csp.sentinel.dashboard.server", "localhost:7080");
        //API端口
        //System.setProperty("csp.sentinel.api.port", "localhost:8719");
        InitExecutor.doInit();
        SentinelRule.initSentinelRule();
    }
}

另外

可以用spring cloud alibaba sentinel的包,可以直接配置,我们在这没有使用,只是使用springboot去实现
按照starter的制作sentinel模式,可以制作定义的sentinel规则

外传

😜 原创不易,如若本文能够帮助到您的同学
🎉 支持我:关注我+点赞👍+收藏⭐️
📝 留言:探讨问题,看到立马回复
💬 格言:己所不欲勿施于人 扬帆起航、游历人生、永不言弃!🔥

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南巷Dong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值