Sentinel规则

1 Sentinel规则

1 流控规则

流量控制,其原理是监控应用流量的QPS(每秒查询率) 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

1: 点击簇点链路,我们就可以看到访问过的接口地址,然后点击对应的流控按钮,进入流控规则配置页面。新增流控规则界面如下:

Sentinel规则_第1张图片

资源名:唯一名称,默认是请求路径,可自定义

针对来源:指定对哪个微服务进行限流,默认指default,意思是不区分来源,全部限制

阈值类型/单机阈值

  1. QPS(每秒请求数量): 当调用该接口的QPS达到阈值的时候,进行限流
  2. 线程数:当调用该接口的线程数达到阈值的时候,进行限流

是否集群:暂不需要集群

接下来我们以QPS为例来研究限流规则的配置

1.1 简单配置

我们先做一个简单配置,设置阈值类型为QPS,单机阈值为3。即每秒请求量大于3的时候开始限流,接下来,在流控规则页面就可以看到这个配置

Sentinel规则_第2张图片

然后快速访问 /order/message1 接口,观察效果。此时发现,当QPS > 3的时候,服务就不能正常响应,而是返回Blocked by Sentinel (flflow limiting)结果。

Sentinel规则_第3张图片

1.2 配置流控模式

点击上面设置流控规则的编辑按钮,然后在编辑页面点击高级选项,会看到有流控模式一栏。

Sentinel规则_第4张图片

sentinel共有三种流控模式,分别是:

  1. 直接(默认):接口达到限流条件时,开启限流
  2. 关联:当关联的资源达到限流条件时,开启限流 [适合做应用让步]
  3. 链路:当从某个接口过来的资源达到限流条件时,开启限流

下面呢分别演示三种模式:

直接流控模式

直接流控模式是最简单的模式,当指定的接口达到限流条件时开启限流。上面案例使用的就是直接流控模式。

关联流控模式

关联流控模式指的是,当指定接口关联的接口达到限流条件时,开启对指定接口开启限流。

1步:配置限流规则, 将流控模式设置为关联,关联资源设置为的 /order/message2

Sentinel规则_第5张图片

4步:访问/order/message1,会发现已经被限流

Sentinel规则_第6张图片

链路流控模式(了解) 

链路流控模式指的是,当从某个接口过来的资源达到限流条件时,开启限流。它的功能有点类似于针对来源配置项,区别在于:针对来源是针对上级微服务,而链路流控是针对上级接口,也就是说它的粒度更细。

1步: 编写一个service,在里面添加一个方法message

@Service 
public class OrderServiceImpl3 { 
@SentinelResource("message") 
public void message() { 
System.out.println("message"); 
} 
}

2步: 在Controller中声明两个方法,分别调用service中的方法

@RestController 
@Slf4j 
public class OrderController3 { 
@Autowired 
private OrderServiceImpl3 orderServiceImpl3; 
@RequestMapping("/order/message1") 
public String message1() { 
orderServiceImpl3.message(); 
return "message1"; 
}
@RequestMapping("/order/message2") 
public String message2() { 
orderServiceImpl3.message(); 
return "message2"; 
} 
}

3: 禁止收敛URL的入口 context

从1.6.3 版本开始,Sentinel Web fifilter默认收敛所有URL的入口context,因此链路限流不生效。

1.7.0 版本开始(对应SCA的2.1.1.RELEASE),官方在CommonFilter 引入了

WEB_CONTEXT_UNIFY 参数,用于控制是否收敛context。将其配置为 false 即可根据不同的

URL 进行链路限流。

SCA 2.1.1.RELEASE之后的版本,可以通过配置spring.cloud.sentinel.web-context-unify=false即

可关闭收敛  我们当前使用的版本是SpringCloud Alibaba 2.1.0.RELEASE,无法实现链路限流。

目前官方还未发布SCA 2.1.2.RELEASE,所以我们只能使用2.1.1.RELEASE,需要写代码的形式实 现

(1) 暂时将SpringCloud Alibaba的版本调整为2.1.1.RELEASE

2.1.1.RELEASE

(2) 配置文件中关闭sentinelCommonFilter实例化

spring: 
  cloud:
    sentinel: 
      filter: 
        enabled: false

(3) 添加一个配置类,自己构建CommonFilter实例

@Configuration 
public class FilterContextConfig { 
@Bean 
public FilterRegistrationBean sentinelFilterRegistration() { 
FilterRegistrationBean registration = new FilterRegistrationBean(); 
registration.setFilter(new CommonFilter()); 
registration.addUrlPatterns("/*"); 
// 入口资源关闭聚合 
registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false"); 
registration.setName("sentinelFilter"); 
registration.setOrder(1); 
return registration; 
} 
} 

4: 控制台配置限流规则

Sentinel规则_第7张图片

1.3 配置流控效果

  1. 快速失败(默认): 直接失败,抛出异常,不做任何额外的处理,是最简单的效果
  2. Warm Up:它从开始阈值到最大QPS阈值会有一个缓冲阶段,一开始的阈值是最大QPS阈值的1/3,然后慢慢增长,直到最大阈值,适用于将突然增大的流量转换为缓步增长的场景。
  3. 排队等待:让请求以均匀的速度通过,单机阈值为每秒通过数量,其余的排队等待; 它还会让设置一个超时时间,当请求超过超时间时间还未处理,则会被丢弃。

2 降级规则 

降级规则就是设置当满足什么条件的时候,对服务进行降级。Sentinel提供了三个衡量条件:

  1. 平均响应时间 :当资源的平均响应时间超过阈值(以 ms 为单位)之后,资源进入准降级状态。如果接下来 1s 内持续进入 5 个请求,它们的 RT都持续超过这个阈值,那么在接下的时间窗口(以 s 为单位)之内,就会对这个方法进行服务降级。

    Sentinel规则_第8张图片

  2. 异常比例:当资源的每秒请求量>=5,并且每秒异常总数占通过量的比值超过阈值之后,资源进入降级状态,即在接下的时间窗口智能,对这个方法的调用都会自动地返回。异常比率的阈值范围是[0.0,1.0],代表0%~100%

3 热点规则  

热点参数流控规则是一种更细粒度的流控规则, 它允许将规则具体到参数上。

热点规则简单使用

1: 编写代码

@RequestMapping("/order/message3")
@SentinelResource(value = "message3")
//注意这里必须使用这个注解标识,热点规则不生效
public String message3(String name, Integer age) { return name + age; }

Sentinel规则_第9张图片

第2步:分别用两个参数访问,会发现只对第一个参数限流了

Sentinel规则_第10张图片

热点规则增强使用

参数例外项允许对一个参数的具体值进行流控编辑刚才定义的规则,增加参数例外项

扩展: 自定义异常返回

//异常处理页面
@Component
public class ExceptionHandlePage implements UrlBlockHandler {
    //BlockException 异常接口,包含Sentinel的五个异常
    // FlowException 限流异常
    // DegradeException 降级异常
    // ParamFlowException 参数限流异常
    // AuthorityException 授权异常
    // SystemBlockException 系统负载异常
    @Override
    public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException e) throws IOException {
        response.setContentType("application/json;charset=utf-8");
        ResponseData data = null;
        if (e instanceof FlowException) {
             data = new ResponseData(-1, "接口被限流了...");
        }
        else if (e instanceof DegradeException) {
            data = new ResponseData(-2, "接口被降级了...");
        }
        response.getWriter().write(JSON.toJSONString(data));
    }
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    class ResponseData{
        private Integer id;
        private String msg;

    }
}

你可能感兴趣的:(spring,java,分布式)