Sentinel简单使用

本文介绍了SpringCloudAlibabaSentinel,一个开源的流量控制和熔断框架,详细讲解了如何在SpringBoot项目中实现限流和熔断功能,包括添加依赖、定义资源、配置规则以及验证效果。
摘要由CSDN通过智能技术生成

1、Sentinel 简介

Spring Cloud Alibaba Sentinel 是一个开源的流量控制熔断框架,是Spring Cloud生态系统中的一个组件。Sentinel的主要功能是实时监控微服务应用的流量,包括入站和出站的流量,并提供流量控制、熔断降级、系统负载保护和热点参数保护等功能。它可以帮助开发者快速识别和处理应用程序中的故障和异常,并保障应用程序的稳定性和可靠性。

2、Sentinel 简单使用

2.1、实现限流功能

Sentinel的使用主要分为以下4步:

① 添加 Sentinel 依赖

② 定义资源

③ 定义规则

④ 验证效果

这里使用简单的maven工程来使用Sentinel。

① 添加依赖

首先我们要创建一个maven工程,勾选Spring Web跟Spring Cloud Alibaba Sentinel这两个依赖

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

② 定义资源

这里有两种定义资源的方式

方法一:通过代码定义

方法二:通过注解定义(基本使用的是这一种)

创建controller文件,这里我创建的是UserController,里面定义了两个方法:getId() 和getName()。分别用两种方式来定义资源

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.cglib.core.Block;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;


@RestController
@RequestMapping("/user")
public class UserController {
    // 方法一
    @RequestMapping("/getid")
    public String getId(){
        try (Entry entry= SphU.entry("getid")){ // 定义资源
            // 正常执行的业务逻辑
            return "Id:"+new Random().nextInt(100);
        }catch (BlockException blockException){
            // 如果执行到此处,说明当前资源已经被限流或熔断
            return "被限制";
        }
    }

    
    // 方法二 注解定义资源
    @SentinelResource(value = "getname",
            blockHandler = "myBlockHander")
    @RequestMapping("/getname")
    public String getName(){
        return "Name:"+new Random().nextInt(100);
    }
    // 限流之后执行的方法
    public String myBlockHander(BlockException blockException){
        return "被限制了";
    }
}

@SentinelResource 注解属性说明:
value:自定义要设置的资源名称,必需项(不能为空)
entryType:资源调用的流量类型:入口流量(EntryType.IN)和出口流量(EntryType.OUT),注意系统规则只对 IN 生效。
blockHandler/blockHandlerClass:限流和熔断时执行 BlockException 所对应的方法名。(以上面的案例来说调用getName方法出现问题,被限流之后,执行的是myBlockHander方法。)

fallback/fallbackClass:非 BlockException 时,其他非限流、非熔断时异常对应的方法。
exceptionsToIgnore:用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

注意事项:

1、1.6.0 之前的版本 fallback 函数只针对熔断降级异常(DegradeException)进行处理,不能针对业务异常进行处理。

2、blockHandler使用注意:

        (1)blockHandler 返回方法的类型必须要跟限流的原方法返回类型一样

        (2)blockHandler 方法必须要有 BlockException 异常参数

        (3)blockHandler 方法参数必须跟限流原方法参数一样

 ③ 定义规则

在启动类里添加定义规则的方法,这里只对 getId方法进行限流。

flowRule.setResource("getid")里的 “getid” 修改成 “getname” 就变成对getName方法进行限流。

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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


@SpringBootApplication
public class SentinelDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SentinelDemoApplication.class, args);
        // 启动的时候执行限流规则
        initFlowRules();
    }

    // 定义限流规则
    private static void initFlowRules(){
        List<FlowRule> rules=new ArrayList<>();
        System.out.println("cwx真帅");
        // 定义一个限流规则
        FlowRule flowRule=new FlowRule();
        flowRule.setResource("getid"); // 资源名|必须参数
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 限流指标:QPS/线程数 |必须参数
        flowRule.setCount(1);  // 限流数量(上一步 QPS 或线程数的值) |必须参数
         flowRule.setStrategy(RuleConstant.STRATEGY_DIRECT); //调用关系限流策略【非必须设置】
         flowRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 流控效果【非必须设置】
         flowRule.setClusterMode(false); // 是否集群限流【非必须设置,默认非集群】

        rules.add(flowRule);

        FlowRuleManager.loadRules(rules);
    }
}

 方法参数解析
setStrategy:设置调用关系限流策略,包含的值有:
        直接(RuleConstant.STRATEGY_DIRECT)【默认值】
        链路(RuleConstant.STRATEGY_RELATE)
        关联(RuleConstant.STRATEGY CHAIN)。
setControlBehavior:设置流控效果,包含的值有:
        直接拒绝(RuleConstant.CONTROL BEHAVIOR_DEFAULT)【默认值】

        冷启动(RuleConstant.CONTROL BEHAVIOR WARM UP)        

        匀速启动(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)

        冷启动+匀速启动(RuleConstant.CONTROL BEHAVIOR WARM UP RATE LIMITER)

④ 验证效果

启动应用程序,连续访问 getid服务。(将flowRule.setResource("getid")里的 “getid” 修改成 “getname” 就变成对getName方法进行限流。)

localhost:8080/user/getid

2.2、实现熔断(降级)功能

 熔断(降级)功能的实现跟限流类似,唯一不同的是规则不同。也就是只需要调整第③步的定义规则。

在启动类上添加熔断的定义规则方法

// 设置熔断(降级)规则
    private static void initDegradeRules()
    {
        List<DegradeRule> degradeRules=new ArrayList<>();
        // 设置一条熔断规则
        DegradeRule degradeRule=new DegradeRule();
        degradeRule.setResource("getname"); //熔断的资源名
        // // 熔断类型:【慢调用】、异常比例、异常个数
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
    // 熔断类型的值,如果是慢调用就是慢调用的值,单位是毫秒; 异常比例 / 异常个数 模式下为对应的值
        degradeRule.setCount(10);
        degradeRule.setStatIntervalMs(1000); // 熔断的统计时间,单位是毫秒
        degradeRule.setSlowRatioThreshold(0.5); // 慢调用比例,此值是 0~1 之间的小数
        // 熔断的最小请求数,请求数小于该值时,及时异常比例超过阈值也不会熔断
        degradeRule.setMinRequestAmount(1);
        degradeRule.setTimeWindow(5); // 熔断的时长,时间单位是秒

        degradeRules.add(degradeRule);
        DegradeRuleManager.loadRules(degradeRules);
    }

这里设置的意思是:选择 慢调用 的模式,在1秒内有超过50%的请求的请求时长超过10毫秒 且 请求数目超过1个,触发熔断,熔断时长为5秒。

方法说明:

resoure:资源名,即规则的作用对象。

grade:熔断策略,分别有 慢调用比例、异常比例、异常数策略。

count:慢调用比例模式下为慢调用临界RT(超出该值即为慢调用);异常比例/异常数模式下为对应的阈值。

timeWindow:熔断时长,单位为 秒/s。

minRequestAmount:熔断触发的最小请求数,请求数小于该值时,即使异常比例超出阈值也不会熔断(1.7.0 引入)

statIntervalMs:统计时长(单位为毫秒/ms),如60*1000代表分钟级(1.8.0引入)

slowRatioThreshold:慢调用比例阈值,仅慢调用比例模式有效(1.8.0引入)

注:熔断(降级)也是会触发@SentinelResource中的 blockHandler 方法,只不过他和限流抛出的 BlockException 不同。

在main方法中调用该方法,熔断跟限流是可以同时实现的,看哪个先执行,就显示哪个的效果。

public static void main(String[] args) {
        SpringApplication.run(SentinelDemoApplication.class, args);
        initFlowRules(); // 启动的时候执行限流规则
        initDegradeRules(); // 启动的时候执行熔断规则
    }

修改controller

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;

@RestController
@RequestMapping("/user")
public class UserController {
    // 方法一
    @RequestMapping("/getid")
    public String getId(){
        try (Entry entry= SphU.entry("getid")){ // 定义资源
            // 正常执行的业务逻辑
            return "Id:"+new Random().nextInt(100);
        }catch (BlockException blockException){
            // 如果执行到此处,说明当前资源已经被限流或熔断
            return "被限制";
        }
    }

    // 方法二
    @SentinelResource(value = "getname",
            blockHandler = "myBlockHander")
    @RequestMapping("/getname")
    public String getName() throws InterruptedException {
        Thread.sleep(100);
        return "Name:"+new Random().nextInt(100);
    }

    // 限流或者熔断之后执行的方法
    public String myBlockHander(BlockException blockException){
        if(blockException instanceof FlowException){
            // 限流异常
            return "您被限流了";
        }else if(blockException instanceof DegradeException){
            // 熔断异常
            return "您被熔断了";
        }
        return "被限制了";
    }
}

访问 localhost:8080/user/getname

  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值