熔断规则

现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。[1]

Sentinel 提供以下几种熔断策略:

  • 慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。

  • 异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是[0.0, 1.0],代表 0% - 100%。

  • 异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

慢调用比例

设置说明:1s内的请求数量大于100,且有超过30%的响应时间大于2000ms,服务熔断10s后进入HALF-OPEN 状态,如果下一次请求的响应时间超过2000ms,服务会再次熔断。

发生熔断:

如果是设置的是方法签名的熔断,代表如果发送熔断,处理的方法为自定义的方法。如下面方法,执行getFallBack方法。

    /**
* 根据id查询部门
*/
@SentinelResource(fallback = "getFallBack")
@GetMapping("/get/{id}")
public Depart get(@PathVariable Long id) {
return restTemplate.getForObject(PROVIDER_URL + "/get/" + id, Depart.class);
} /**
* 服务降级使用的方法
*/
public Depart getFallBack(Long id, Throwable t) {
log.info("id = " + id);
log.info("throwable = " + t.getMessage());
Depart depart = new Depart();
depart.setId(id);
depart.setName("no this depart");
return depart;
}

也可以给需要熔断的方法设置别名,如我们给get/{id},设置资源别名为value = "get"。fallback一定要设置,不让会出现500空白页

    /**
* 根据id查询部门
*/
@SentinelResource(value = "get", fallback = "getFallBack")
@GetMapping("/get/{id}")
public Depart get(@PathVariable Long id) {
return restTemplate.getForObject(PROVIDER_URL + "/get/" + id, Depart.class);
}

资源名为我们设置的别名。

需要注意的是,在控制台配置的熔断规则在服务重启后会丢失,但是我们可以在代码中进行设置,这样重启服务配置依然在。

慢比例调用代码实现

可以利用sentinel提供的api在代码中进行设置,或者自定义配置类在配置类中定义。

package com.zjw;

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import java.util.ArrayList;
import java.util.List; @SpringBootApplication
public class ConsumerSentinel8080Application { public static void main(String[] args) {
SpringApplication.run(ConsumerSentinel8080Application.class, args);
//初始化熔断规则
initDegradeRule();
} /**
* 初始化熔断规则
*/
private static void initDegradeRule() {
DegradeRuleManager.loadRules(configDegradeRule());
} private static List<DegradeRule> configDegradeRule(){
List<DegradeRule> degradeRuleList = new ArrayList<>();
DegradeRule rule = new DegradeRule();
// sentinel资源名称,这里填入value值,@SentinelResource(value = "get", fallback = "getFallBack")
rule.setResource("get");
// 熔断策略,默认是慢调用比例,0: average RT, 异常比例 1: exception ratio, 异常数 2: exception count
rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);//慢调用比例
// rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);//异常比例
// rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);//异常数
// 慢调用比例策略下为最大RT,响应时间,单位ms;异常比例策略下为比例阈值[0.0, 1.0];异常数策略下为异常数,int
rule.setCount(800);
// 比例阈值,默认为1.0,即100%。慢调用比例策略才需要设置
rule.setSlowRatioThreshold(0.5D);
// 熔断时长,单位s
rule.setTimeWindow(10);
// 最小请求数
rule.setMinRequestAmount(200);
// 统计时长,单位ms,默认为1000ms
rule.setStatIntervalMs(1000); degradeRuleList.add(rule);
return degradeRuleList;
}
}

自定义异常处理器(返回响应流)

默认的降级响应在DefaultBlockExceptionHandler定义,该类继承了BlockExceptionHandler,如果我们自定义异常处理器,可以继承BlockExceptionHandler,并且交给Spring管理。

自定义异常处理类

package com.zjw.handler;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component; import java.io.PrintWriter; /**
* @since 2023/12/03 23:22
*/
@Component
public class CustomBlockExceptionHandler implements BlockExceptionHandler { @Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
// Return 429 (Too Many Requests) by default.
response.setStatus(429); String msg = "";
if (e instanceof AuthorityException) {
msg = "Blocked by Sentinel (authority limiting)";
} else if (e instanceof DegradeException) {
msg = "Blocked by Sentinel (degrade limiting)";
} else if (e instanceof FlowException) {
msg = "Blocked by Sentinel (flow limiting)";
} else if (e instanceof ParamFlowException) {
msg = "Blocked by Sentinel (param flow limiting)";
} else if (e instanceof SystemBlockException) {
msg = "Blocked by Sentinel (system limiting)";
} else {
msg = "Blocked by Sentinel";
}
PrintWriter out = response.getWriter();
out.print(msg);
out.flush();
out.close();
}
}

BlockException有五个子类。

如果定义的fallback处理方法是不会走到自定义异常类的。否则会进入自定义异常类处理。

测试

添加熔断规则

controller方法

    @GetMapping("/list")
public List<Depart> list() {
return (List<Depart>)restTemplate.getForObject(PROVIDER_URL + "/list", List.class);
}

多次请求返回结果

自定义异常处理器(返回页面)

异常处理器

package com.zjw.handler;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component; /**
* 自定义异常处理器 返回页面
* @since 2023/12/03 23:22
*/
@Component
public class CustomBlockExceptionHandler implements BlockExceptionHandler { @Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
String page = "/default.html";
if (e instanceof AuthorityException) {
page = "/authorityException.html";
} else if (e instanceof DegradeException) {
page = "/degradeException.html";
} else if (e instanceof FlowException) {
page = "/flowException.html";
} else if (e instanceof ParamFlowException) {
page = "/paramFlowException.html";
} else if (e instanceof SystemBlockException) {
page = "/systemBlockException.html";
}
request.getRequestDispatcher(page).forward(request,response);
}
}

如果需要重定向,可以这样写:

/**
* 自定义异常处理器 重定向 适用前后端分离
* @since 2023/12/03 23:22
*/
@Component
public class CustomBlockExceptionHandler implements BlockExceptionHandler { @Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
String page = "https://www.taobao.com";
if (e instanceof AuthorityException) {
page = "https://www.baidu.com";
} else if (e instanceof DegradeException) {
page = "https://www.baidu.com";
} else if (e instanceof FlowException) {
page = "https://www.baidu.com";
} else if (e instanceof ParamFlowException) {
page = "https://www.baidu.com";
} else if (e instanceof SystemBlockException) {
page = "https://www.baidu.com";
}
response.sendRedirect(page);
}
}

定义页面

/resource/METE-INF/resource/degradeException.html

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>熔断</title>
</head>
<body>
系统发生熔断。
</body>
</html>

测试

测试方法同上。


  1. https://github.com/alibaba/Sentinel/wiki/熔断降级

Sentinel——熔断规则的更多相关文章

  1. 一个名叫Sentinel-Rules-SDK的组件,使得Sentinel的流控&熔断规则的配置更加方便

    原文链接:一个名叫Sentinel-Rules-SDK的组件,使得Sentinel的流控&熔断规则的配置更加方便 1 Sentinel 是什么? 随着微服务的流行,服务和服务之间的稳定性变得越 ...

  2. Sentinel熔断降级

    sentinel流量控制 Sentinel流量控制&服务熔断降级介绍 流量控制介绍 在这里我用景区的例子解释一下 一个旅游景点日接待游客数量为8K,8K以后的游客就无法买票进去景区. 对应编程 ...

  3. Sentinel熔断与限流

    1.简介 在线文档: https://sentinelguard.io/zh-cn/docs/system-adaptive-protection.html 功能: 流量控制 速率控制 熔断和限流 和 ...

  4. Sentinel Dashboard 规则 持久化到Nacos

    本篇文章基于sentinel1.8.4版本进行改造的.本篇主要记录改造步骤 1.下载源码 https://github.com/alibaba/Sentinel 2.打开下载的sentinel,到se ...

  5. Sentinel-流量防卫兵

    1.背景 1.1 简介 Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性. Sentinel 具有以下特征 丰富的应用场景:Sentinel 承接了阿里巴 ...

  6. Spring Cloud Alibaba(三)Sentinel之熔断降级

    本项目演示如何使用 Sentinel 完成 Spring Cloud 应用的熔断降级调用. Sentinel 是阿里巴巴开源的分布式系统的流量防卫组件,Sentinel 把流量作为切入点,从流量控制, ...

  7. Spring Cloud alibaba网关 sentinel zuul 四 限流熔断

    spring cloud alibaba 集成了 他内部开源的 Sentinel 熔断限流框架 Sentinel 介绍 官方网址 随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentine ...

  8. Sentinel之熔断降级

    除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一.由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积.Sentinel 熔断降级会在调用链路 ...

  9. Alibaba Sentinel 限流与熔断初探(技巧篇)

    目录 1.Sentinel 是什么 ?主要能解决什么问题? 2.限流与熔断的使用场景 3.Sentinel 源码结构 4.在 IntelliJ IDEA 中运行 Sentine Demo 温馨提示:源 ...

  10. SpringCloud Gateway高阶之Sentinel限流、熔断

    前言 为什么需要服务熔断和降级?微服务是当前业界的一大趋势,原理就是将单一职责的功能模块独立化为子服务,降低服务间的耦合,服务间互相调用.但是这样也会出现一些问题: 上图中大量微服务互相调用,存在大量 ...

随机推荐

  1. Mac安装Scala2.12

    一.下载Scala brew install scala@2.12 二.设置环境变量 vim ~/.bash_profile export SCALA_HOME=/usr/local/opt/scal ...

  2. 1.Vue3 配置开发-测试环境

    1.根目录新建.env.testing..env.donline文件 2.package.json=>scripts中配置 "start": "vue-cli-se ...

  3. [SDOI2009] 晨跑 题解

    每个点拆成入点和出点. 发现每个点.每条边都只能经过一次,所以所有边的容量都是 \(1\). #include<bits/stdc++.h> #define ll long long us ...

  4. 企业付款到零钱(微信小程序提现,用户提现到零钱)

    pom 增加 <dependency> <groupId>com.github.binarywang</groupId> <artifactId>wei ...

  5. RNN、lstm和GRU推导

    RNN:(Recurrent Neural Networks)循环神经网络 第t层神经元的输入,除了其自身的输入xt,还包括上一层神经元的隐含层输出st−1 每一层的参数U,W,V都是共享的 lstm ...

  6. Ansible - [11] Roles

    前言 Q1:什么是Roles 在实际生产环境中,会编写大量的playbook文件来实现不同的功能.而且,每个playbook还可能会调用其他文件(变量文件),对于海量的.无规律的文件,管理是个问题.A ...

  7. ActiViz 在 .NET 环境下的 CT 图像渲染

    1. 什么是 ActiViz? ActiViz 是 VTK(Visualization Toolkit) 的 .NET 封装,提供了强大的 3D 计算机图形渲染功能,广泛应用于 医学影像(CT.MRI ...

  8. 使用Shader画常见的数学函数

    使用Shader画常见的数学函数 本篇博文的灵感来自于Shader Books这一小节:https://thebookofshaders.com/05/?lan=ch 代码运行网站:http://ed ...

  9. Netty源码—6.ByteBuf原理一

    大纲 1.关于ByteBuf的问题整理 2.ByteBuf结构以及重要API 3.ByteBuf的分类 4.ByteBuf分类的补充说明 5.ByteBuf的主要内容分三大方面 6.内存分配器Byte ...

  10. centos7 下全局配置最新版的golang语言开发环境

    按照以下步骤进行操作: 前往Go官方网站下载页面(https://golang.org/dl/)查找最新版本的Go二进制文件. 使用wget命令下载最新版本的Go二进制文件.例如,如果最新版本是1.1 ...