熔断规则

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

    1.检查 whereis nodejs whereis npm 2.下载 wget -c https://npm.taobao.org/mirrors/node/v12.12.0/node-v12.1 ...

  2. WPF的Dispatcher类里的BeginInvoke,Invoke,InvokeAsync

    原文地址:https://blog.csdn.net/niuge8905/article/details/81117989 深入了解 WPF Dispatcher 的工作原理(Invoke/Invok ...

  3. autohue.js:让你的图片和背景融为一体,绝了!

    需求 先来看这样一个场景,拿一个网站举例 这里有一个常见的网站 banner 图容器,大小为为 1910*560 ,看起来背景图完美的充满了宽度,但是图片原始大小时,却是: 它的宽度只有 1440 , ...

  4. 函数static的作用

    限制作用域和保持状态 ‌函数static的作用主要体现在限制作用域和保持状态两个方面.‌‌1 限制作用域 ‌静态全局变量‌:在全局变量前加上static关键字,该变量就被定义成为一个静态全局变量.这种 ...

  5. Mysql创建数据库字符集的选择

    字符集选择: 在国内正常都是用[UTF-8] 排序选择:排序一般分为两种:utf_bin和utf_general_cibin 是二进制, a 和 A 会别区别对待. utf8_general_ci [ ...

  6. flutter - [02] 基本语法

    题记部分 一.注释 ///这是一个注释 //这也是个注释 /* 这还是个注释 */ void main(List<String> args) { print ('你好 dart'); } ...

  7. Linux - openssh通过源码build rpm包

    # 安装依赖包 yum install --downloadonly --downloaddir=/home/rpm-install rpm-build gcc gcc-c++ glibc glibc ...

  8. 【Ryan】: linux下安装ftp

    在 Linux 系统下安装 FTP 服务器可以使用多种软件,其中最常见的是 vsftpd(Very Secure FTP Daemon)和 ProFTPD(Professional FTP Daemo ...

  9. AI 实践|零成本生成SEO友好的TDK落地方案

    之前写过一篇文章「Google搜索成最大入口,简单谈下个人博客的SEO」,文章里介绍了网页的描述信息TDK(Title.Description和Keywords)对SEO的重要作用,尽管已经意识到了T ...

  10. Font-awesome失效恢复

    Font-awesome失效恢复策略 可能的原因有: 1.用了收费pro的版本,没充钱. Font Awesome 6 字体分为 Free 和 Pro 两个版本.Font Awesome 6 Free ...