springboot sentinel 整合 规则详情和代码实现-分布式/微服务流量控制

文章目录

  • sentinel控制台安装
  • 目标
  • 版本说明
  • sentinel 规则整合验证
    • pom.xml
    • 配置注解拦截
    • 资源控制规则---内存模式
    • 测试controller
    • 客户端接入控制台
  • 测试
    • sentinel控制台
    • 接口调用
  • 下一篇:配置持久化策略规则
  • 外传

sentinel控制台安装

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

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

目标

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

版本说明

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

sentinel 规则整合验证

官网地址:https://sentinelguard.io/zh-cn/docs/basic-api-resource-rule.html

springboot sentinel 整合 规则详情和代码实现-分布式/微服务流量控制_第1张图片

pom.xml


        
        <dependency>
            <groupId>com.alibaba.cspgroupId>
            <artifactId>sentinel-coreartifactId>
        dependency>
        
        <dependency>
            <groupId>com.alibaba.cspgroupId>
            <artifactId>sentinel-transport-simple-httpartifactId>
        dependency>
        
        <dependency>
            <groupId>com.alibaba.cspgroupId>
            <artifactId>sentinel-annotation-aspectjartifactId>
        dependency>
        
        <dependency>
            <groupId>com.alibaba.cspgroupId>
            <artifactId>sentinel-parameter-flow-controlartifactId>
        dependency>

配置注解拦截

注解使用的话,必须要先初始化配置:

package org.lwd.microservice.boot.plat.controller;

import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 注解方式配置
 *
 * @author weidong
 * @version V1.0.0
 * @since 2023/7/14
 */
@Configuration
public class SentinelConfig {
    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}


资源控制规则—内存模式

资源控制规则–在项目中配置规则
sentinel控制台可以修改规则,但是仅限于临时使用,当项目重启后,临时规则消失

package org.lwd.microservice.boot.plat.controller;

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
//为什么不用这种方式加载,我门使用的是纯springboot的整合方式,现在,是在application启动后,再初始化sentinel连接sentinel,所以启动过程中加载,是不能初始化到控制台
public class SentinelRule {

    public SentinelRule(){
        initFlowQpsRule();
        initDegradeRule();
        initSystemProtectionRule();
    }

    /**
     * 流量控制规则
     *
     * Field        说明                          默认值
     * resource     资源名,资源名是限流规则的作用对象
     * count        限流阈值
     * grade        限流阈值类型,QPS 或线程数模式       QPS 模式
     * limitApp     流控针对的调用来源               default,代表不区分调用来源
     * strategy     调用关系限流策略:直接、链路、关联   根据资源本身(直接)
     * controlBehavior  流控效果(直接拒绝 / 排队等待 / 慢启动模式),不支持按调用关系限流     直接拒绝
     */
//    @PostConstruct
    private 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 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(10);
        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 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 void initAuthorityRule(){
        AuthorityRule rule = new AuthorityRule();
        rule.setResource("test");
        rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
        rule.setLimitApp("appA,appB");
        AuthorityRuleManager.loadRules(Collections.singletonList(rule));
    }



}

测试controller

可适应controller或者service,关键字在于资源

package org.lwd.microservice.boot.plat.controller;

import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 流量控制-测试控制器
 *
 * @author weidong
 * @version V1.0.0
 * @since 2023/7/14
 */
@Slf4j
@RestController
@RequestMapping("/sentinel/")
@CrossOrigin
public class SentinelController {

    @SentinelResource(value = "sayHello",
            fallback = "circuitBreakerFallback", blockHandler = "sayHelloExceptionHandler", entryType = EntryType.IN)
    @GetMapping(value = "/sayHello")
    public String testInterGet(String name) {
        log.info("----hello sentinel---:{}", name);
        return JSON.toJSONString(name);
    }

    /**
     * 熔断降级
     * @return
     */
    @SentinelResource(value = "circuitBreaker", fallback = "circuitBreakerFallback", blockHandler = "sayHelloExceptionHandler")
    @GetMapping(value = "/circuitBreaker")
    public String circuitBreaker(String name){
        if ("lwd".equals(name)){
            return "hello,"+ name;
        }
        throw new RuntimeException("发生异常");
    }

    public String circuitBreakerFallback(String name){
        log.info("----熔断降级处理---:{}",name);
        return "服务异常,熔断降级, 请稍后重试!";
    }

    public String sayHelloExceptionHandler(String name, BlockException ex){
        log.info("----限流降级处理---:{}",name);
        return "访问过快,限流降级, 请稍后重试!";
    }


}



客户端接入控制台

启动时加入 JVM 参数-Dcsp.sentinel.dashboard.server=consoleIp:port指定控制台地址和端口。更多的参数参见启动参数文档。

或者我们使用在java中设置启动参数
启动类

package org.lwd.microservice.boot.plat;

import com.alibaba.csp.sentinel.init.InitExecutor;
import org.lwd.microservice.boot.middle.runtime.util.YmlUtils;
import org.lwd.microservice.boot.plat.controller.SentinelRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @author weidong
 * @version V1.0.0
 * @description
 * @since 2023/4/7
 */
@SpringBootApplication
public class PlatApplication {

    public static void main(String[] args) {
        System.setProperty("project.name", YmlUtils.getApplicationName());
        ConfigurableApplicationContext context = SpringApplication.run(PlatApplication.class, args);

        // 连接到控制台,与sentinel控制台通信
        //System.setProperty("project.name", context.getEnvironment().getProperty("spring.application.name", "sentinel"));
        //System.setProperty("csp.sentinel.dashboard.server", context.getEnvironment().getProperty("sentinel.dashboard.server", "localhost:7080"));
        //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();
        new SentinelRule();

    }

}


测试

sentinel控制台

控制台会在左侧显示启动的项目,并新增控制策略【控制台新增策略,生命周期只在客户端项目运行,一旦重启就没有了】
控制台:http://localhost:7080/

springboot sentinel 整合 规则详情和代码实现-分布式/微服务流量控制_第2张图片
springboot sentinel 整合 规则详情和代码实现-分布式/微服务流量控制_第3张图片
springboot sentinel 整合 规则详情和代码实现-分布式/微服务流量控制_第4张图片

接口调用

测试限流接口:http://localhost:8022/sentinel/sayHello?name=lwd
springboot sentinel 整合 规则详情和代码实现-分布式/微服务流量控制_第5张图片

测试熔断接口:http://localhost:8022/sentinel/circuitBreaker?name=zhansan
http://localhost:8022/sentinel/circuitBreaker?name=lwd

springboot sentinel 整合 规则详情和代码实现-分布式/微服务流量控制_第6张图片

springboot sentinel 整合 规则详情和代码实现-分布式/微服务流量控制_第7张图片

过设定的时间访问:
springboot sentinel 整合 规则详情和代码实现-分布式/微服务流量控制_第8张图片

下一篇:配置持久化策略规则

使用nacos配置--自己实现
使用springcloudalibaba-sentinel已经实现好了

外传

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

你可能感兴趣的:(分布式微服务,spring,boot,sentinel,分布式)