【JAVA企业级开发】Sentinel的限流控制,熔断降级处理基于OpenFeign(Ribbon)统一Fallback处理的整合和 Sentinel的@SentinelResource注解的应用属性

  • Post author:
  • Post category:java




一级目录



二级目录



三级目录



一 sentinel的默认降级流控的fallback。



1限流降级

除了下载Sentinel控制台之外,sentinel还有javaAPI的方式设置限流降级策略:

限流降级对于OpenFeign和Sentinel整合来说有两种策略:

1.设置ribbon超时时间,调用超时后,自动会降级
(如果不设置,自己测试了一下两个属性默认都是2秒,即不设置则自动使用2秒超时服务降级方案)
#连接服务超时时间为5秒
ribbon.ConnectTimeout=5000
#连接后,处理请求的超时时间为5秒
ReadTimeout: 5000
2其次就是设置Sentinel降级配置,如设置超过平均响应时间则降级
添加以下代码实现降级配置(可以放在启动的main方法里面执行,若放在@Configuration类的静态代码块中执行会注册不了,有bug)
private static void initRtRule() {
    List<DegradeRule> rules = new ArrayList<DegradeRule>();
    DegradeRule rule = new DegradeRule();
    rule.setResource("GET:http://order/getOrder.do");//资源名称
    rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);//降级模式,根据平均响应时间降级
    rule.setCount(1000);//设置平均响应时间为1000ms
    rule.setTimeWindow(10);//设置降级持续时间为10s
    rules.add(rule);
    DegradeRuleManager.loadRules(rules);
}
说明:当持续进入的5个请求响应时间都超过1000ms,接下来的10s内对这个接口的调用都会直接返回并抛出DegradeException,然后执行降级方法
 
ps:添加以下代码可以实现对接口的限流
private static void initFlowQpsRule() {
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule();
    rule.setResource("/getUserOrder.do");
    rule.setCount(1);//限制每秒只能接受1个请求
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);//默认
    rule.setLimitApp("default");//默认
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}
ps:热点限流
public static void initParamFlowRule(){
    List<ParamFlowRule> rules = new ArrayList<>();
    ParamFlowRule rule = new ParamFlowRule();
    //阈值类型:只支持QPS
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    //阈值
    rule.setCount(1);
    //资源名
    rule.setResource("test");
    rule.setParamIdx(0);//指配热点参数的下标
    //统计窗口时间长度
    rule.setDurationInSec(10);

    List<ParamFlowItem> items = new ArrayList<>();
    ParamFlowItem item = new ParamFlowItem();
    item.setClassType(String.class.getTypeName());
    item.setCount(2);
    item.setObject("123456");//需要统计的值

    ParamFlowItem item1 = new ParamFlowItem();
    item1.setClassType(int.class.getName());
    item1.setCount(3);
    item1.setObject("12");

    items.add(item);
    items.add(item1);
    rule.setParamFlowItemList(items);
    rules.add(rule);
    ParamFlowRuleManager.loadRules(rules);

在这里插入图片描述

但是这样子太丑啦。当然我们可以通过@SentinelResource设置定制的fallback、blockhandler方法。



2@SentinelResource注解介绍

@SentinelResource 用于定义资源(

方法

),并提供可选的异常处理和 fallback 配置项。 @SentinelResource 注解包含以下属性:


1value: 资源名称,必需项(不能为空)




2entryType: 入口类型,可选项: EntryType.IN和EntryType.OUT(默认为 EntryType.OUT)



3blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称,可选项。

若未配置,则将 BlockException 直接抛出。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。


4fallback: fallback 函数名称,可选项,仅针对降级功能生效(DegradeException)。

fallback 函数的访问范围需要是 public,参数类型和返回类型都需要与原方法相匹配,并且需要和原方法在同一个类中。业务异常不会进入 fallback 逻辑。

在这里插入图片描述

但是我们也不可能每个限制的方法上面,都要去设置@SentinelResource;这样代码太冗余了。



二使用OpenFeign的统一Fallback

获取控制台:地址

https://github.com/alibaba/Sentinel/releases


启动控制台:

start javaw -jar sentinel-dashboard-1.7.0.jar


Feign 对应的接口中的资源名策略定义:

httpmethod:protocol://requesturl
GET:http://accountprovider/login

在这里插入图片描述

需要注意的是,需要对画线的资源名对应进行策略操作,如果对上级进行操作,fallback返回的仍然是默认值

BlockedbySentinel(flow limiting)

openfeign服务调用接口

package fengbo.service;

import fengbo.entity.Account;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

/*
 * Created by @author LiuChunhang on 2020/7/27.

*/


/**使用openfeign,定制化服务*/

@FeignClient(value = "accountprovider",fallback = SentinelEcho.class)
@Component
public interface FeignOpenServiceFace {
    @RequestMapping(value = "login")
    List<Account> fengbo();
}

openfeigen fallback类

package fengbo.service;

import fengbo.entity.Account;
import org.springframework.stereotype.Component;

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

/**
 * Created by @author LiuChunhang on 2020/7/29.
 */

@Component
public class SentinelEcho  implements  FeignOpenServiceFace{
    @Override
    public List<Account> fengbo() {
        System.out.println("!!!!!!!!!!!!!!!!!");
        ArrayList<Account> accounts = new ArrayList<>();
        Account account = new Account(1,"降级", "降级", "降级", "降级", "降级", 2);
        accounts.add(account);
        return accounts;
    }
}



1流量控制

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

资源名: 唯一名称,默认请求路径
针对来源: Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
阈值类型/单机阈值:
QPS(每秒请求数量):当调用该api的QPS达到阈值的时候,进行限流
线程数:当调用该api的线程数达到阈值的时候,进行限流
是否集群: 不需要集群/不需要集群
流控模式:
直接:api达到限流条件时,直接限流
关联:当关联的资源达到限流阈值时,就限流自己
链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到峰值,就进行限流)【api级别的针对来源】
流控效果:
快速失败:直接失败,抛异常
Warm Up:根据coldFactor(冷加载因子,默认3)的值,从阈值/coldFactor,经过预热时长,才达到设置的QPS阈值
排队等待:匀速排队,让请求以匀速通过,阈值类型必须设置为QPS,否则无效

javaAPI(可以放在启动的main方法里面执行,若放在@Configuration类的静态代码块中执行会注册不了,有bug)

private static void initFlowQpsRule() {
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule();
    rule.setResource("/getUserOrder.do");
    rule.setCount(1);//限制每秒只能接受1个请求
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);//默认
    rule.setLimitApp("default");//默认
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}



2降级策略

在这里插入图片描述

我们通常用以下几种方式来衡量资源是否处于稳定的状态:

平均响应时间 (DEGRADE_GRADE_RT):当资源的平均响应时间超过阈值(DegradeRule 中的 count,以 ms 为单位)之后,资源进入准降级状态。接下来如果持续进入 5 个请求,它们的 RT 都持续超过这个阈值,那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回(抛出 DegradeException)。

异常比例 (DEGRADE_GRADE_EXCEPTION_RATIO):当资源的每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 [0.0, 1.0],代表 0% – 100%。

异常数 (DEGRADE_GRADE_EXCEPTION_COUNT):当资源近 1 分钟的异常数目超过阈值之后会进行熔断。

注意:异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException)不生效。为了统计异常比例或异常数,需要通过 Tracer.trace(ex) 记录业务异常。

javaAPI(可以放在启动的main方法里面执行,若放在@Configuration类的静态代码块中执行会注册不了,有bug)

private static void initRtRule() {
    List<DegradeRule> rules = new ArrayList<DegradeRule>();
    DegradeRule rule = new DegradeRule();
    rule.setResource("GET:http://order/getOrder.do");//资源名称
    rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);//降级模式,根据平均响应时间降级
    rule.setCount(1000);//设置平均响应时间为1000ms
    rule.setTimeWindow(10);//设置降级持续时间为10s
    rules.add(rule);
    DegradeRuleManager.loadRules(rules);
}



3热点规则

在这里插入图片描述

在这里插入图片描述

javaAPI(可以放在启动的main方法里面执行,若放在@Configuration类的静态代码块中执行会注册不了,有bug)

public static void initParamFlowRule(){
    List<ParamFlowRule> rules = new ArrayList<>();
    ParamFlowRule rule = new ParamFlowRule();
    //阈值类型:只支持QPS
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    //阈值
    rule.setCount(1);
    //资源名
    rule.setResource("test");
    rule.setParamIdx(0);//指配热点参数的下标
    //统计窗口时间长度
    rule.setDurationInSec(10);

    List<ParamFlowItem> items = new ArrayList<>();
    ParamFlowItem item = new ParamFlowItem();
    item.setClassType(String.class.getTypeName());
    item.setCount(2);
    item.setObject("123456");//需要统计的值

    ParamFlowItem item1 = new ParamFlowItem();
    item1.setClassType(int.class.getName());
    item1.setCount(3);
    item1.setObject("12");

    items.add(item);
    items.add(item1);
    rule.setParamFlowItemList(items);
    rules.add(rule);
    ParamFlowRuleManager.loadRules(rules);



版权声明:本文为liuchunhang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。