熔断规则

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

    windows系统之netstatt.telnet.tasklist  taskkill 四大常用网络运维命令 Netstat 查看网络状态信息 [用法格式] NETSTAT [-a] [-b] [- ...

  2. @Scheduled参数及cron表达式解释

    @Scheduled支持以下8个参数:1.cron:表达式,指定任务在特定时间执行:2.fixedDelay:表示上一次任务执行完成后多久再次执行,参数类型为long,单位ms:3.fixedDela ...

  3. TOGAF 内容元模型综合指南

    介绍 开放群组架构框架 (TOGAF) 是一种广泛使用的企业架构框架,它提供了一种结构化的方法来设计.规划.实施和管理企业信息技术架构.TOGAF 内容元模型是该框架的重要组成部分,它提供了一种标准化 ...

  4. Kubernetes - [02] 网络通讯方式

    题记部分 一.网络通讯模式   Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平的网络空间中,这在(GCEGoogle Compute Engine)里面是现成的网络模型,Ku ...

  5. MySQL - [04] 分布式部署&主从复制&读写分离

    一.前言 Q1:为什么需要主从复制? 1.在业务复杂的系统中,有一条SQL语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务.使用主从复制,让主库负责写,从库负责读,这样即使主库出现了锁 ...

  6. TIDB 数据库架构概述

    学习目标 题解数据库整体架构 了解 TiDB Server .TiKV.TiFlash.和 PD 的主要功能 文章末尾获取笔记.视频资料,持续更新 体系架构 水平扩容或者缩容 金融级高可用 实时 HT ...

  7. SpringBoot项目war、jar自定义配置application文件的位置

    此篇文章的真正目的应该是关于war包运行在独立tomcat下时,应如何在war包外部配置application.properties,以达到每次更新war包而不用更新配置文件的目的.百度搜素Sprin ...

  8. linux 删除文件提示 opration not permitted 处理方法(宝塔删除文件提示无法删除)

    问题描述:linux系统中使用rm -rf强制删除文件,提示 opration not permitted,无法删除成功(宝塔删除文件提示无法删除),该问题确定为已关闭所有安全软件及防止恶意篡改的软件 ...

  9. 获取Typora激活码的方法主要有以下几种

    ‌官方购买‌:访问Typora官网下载Typora软件.请注意,官网下载版本需购买激活,否则仅有15天试用期.购买费用为89元‌ 1. ‌使用激活工具‌:可以通过下载特定的激活工具来获取激活码.具体步 ...

  10. 使用Python完成设备巡检

    在企业网络中,设备巡检是保持网络稳定性和安全性的核心任务.无论是路由器.交换机,还是防火墙和服务器等设备,都需要定期进行巡检,以确保网络设施的正常运行.然而,传统的设备巡检通常是通过手动登录设备.查看 ...