Sentinel隔离、降级、授权规则详解
文章目录
- Feign整合Sentinel
- 线程隔离
- 熔断降级
- 授权规则
- 自定义异常结果
上一期教程讲解了 Sentinel 的限流规则: Sentinel限流规则,这一期主要讲述 Sentinel 的 隔离、降级和授权规则
虽然限流可以尽量避免因高并发而引起的服务故障,但服务还会因为其它原因而故障。而要将这些故障控制在一定范围,避免雪崩,就要靠线程隔离(舱壁模式)和熔断降级手段了
不管是线程隔离还是熔断降级,都是对客户端(调用方) 的保护
Feign整合Sentinel
在 SpringCloud 中,微服务调用一般都是通过 Feign 来实现的,因此做客户端保护必须整合Feign和Sentinel
Feign 的使用在之前的教程中有详细讲解过:Eureka结合Feign
实现的步骤如下:
1.在调用方的 application.yml 文件中,开启 Feign 对 Sentinel 的支持
feign:sentinel:enabled: true # 开启feign对sentinel的支持
2.为 FeignClient 编写失败后的降级逻辑
这里有两种方式:
① FallbackClass,这种方式无法对远程调用的异常做处理
② FallbackFactory,这种方式可以对远程调用的异常做处理
这里我们选择 FallbackFactory
定义一个类 UserClientFallbackFactory(名字可以任意),然后实现接口 FallbackFactory<UserClient>,这里泛型要和对应的 Feign 客户端对应
@Component
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {@Overridepublic UserClient create(Throwable cause) {return new UserClient() {@Overridepublic String user() {cause.printStackTrace();// 异常时返回空值return "";}};}}
3.在 Feign 客户端的 @FeignClient 注解中,添加属性 fallbackFactory,值就是刚才定义的类的 class 对象
@FeignClient(name = "service2", url = "http://127.0.0.1:8082", fallbackFactory = UserClientFallbackFactory.class)
这里为了方便,就直接定义了对应服务的 url,如果结合了注册中心,这里只需要填写对应的服务名即可
4.启动测试
访问对应服务端点后,进入 Sentinel 控制台,可以看到如下界面,表示 Feign 已经成功整合了 Sentinel

然后添加限流规则,将 QPS 设为 1,测试异常情况

然后快速刷新浏览器,可以发现限流后,返回了空值,即触发了 Feign 客户端的失败降级逻辑

线程隔离
线程隔离有两种方式实现:
1.线程池隔离
这种方式就是将服务消费者的资源划分成一个又一个独立的线程池,假设某一服务提供者挂掉了,也只有一个线程池的资源会被耗尽,不会导致所有的资源被耗尽
优点:
① 支持主动超时(可以通过线程池来控制线程,比如发现某个线程耗时较长,就可以直接终止这个线程)
② 支持异步调用(自己的线程继续接收消息,把调用交给线程池里的线程)
缺点: 线程的额外开销比较大(需要开启的线程较多,同时CPU还需要进行线程的上下文切换)
场景: 低扇出(扇出指的是原本的请求分散后的请求数),扇出越高,需要开启的线程就越多
2.信号量隔离(Sentinel 默认采用)
信号量隔离指的是不会为每个业务创建一个线程池,而是会统计当前业务已经使用的线程数,然后进行限制。当达到这个限制时,就会阻止对这个业务的请求,即限制每个业务能使用的线程数量
优点: 轻量级,无额外开销
缺点:
① 不支持主动超时
② 不支持异步调用
场景: 高频调用、高扇出
下面是两种方式的对比图:

在 Sentinel 控制台中,可以选择阈值类型,共有两种:

① QPS:就是每秒的请求数
② 线程数:是该资源能使用的 tomcat 线程数的最大值。也就是通过限制线程数量,实现舱壁模式,对应信号量隔离
熔断降级
熔断降级是解决雪崩问题的重要手段。其思路是由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值则会熔断该服务,即拦截访问该服务的一切请求。而当服务恢复时,断路器会放行访问该服务的请求
断路器是由内部的状态机实现的:

整个的流程是:正常情况下,断路器关闭,处于 Closed 状态。如果断路器统计的慢调用或异常比例达到失败阈值,会开启断路器,进入 Open 状态,此时的请求会快速失败。直到熔断时间结束,会进入 Half-Open 状态(断路器半开启状态),此时会尝试放行一次请求,如果此次请求成功,则关闭断路器,进入 Closed 状态;如果请求失败,则重新打开断路器,回到 Open 状态,并重复刚才的过程
断路器熔断策略有三种:慢调用、异常比例、异常数
1.慢调用
业务的响应时长(RT)大于指定时长的请求认定为慢调用请求。在指定时间内,如果请求数量超过指定请求数,并且慢调用比例大于设定的阈值,则触发熔断
例如,在 Sentinel 控制台中选择新增降级规则,并填写如下信息


这个表单的信息表示,响应时长(RT) 超过 500ms 的调用是慢调用,统计最近 10000ms 内的请求,如果请求量不少于 10 次,并且慢调用比例不低于 0.5,则触发熔断,熔断时长为 5 秒。然后进入 half-open 状态,放行一次请求做测试
2.异常比例或异常数
统计指定时间内的调用,如果调用次数超过指定请求数,并且出现异常(指的是程序抛出的异常)的比例达到设定的比例阈值(或超过指定异常数),则触发熔断
例如,设置如下的降级规则


这两种设置方式都是一样的,区别在于一个是设置异常比例,一个是设置异常数,但表达的意思都是,统计最近 1000ms 内的请求,如果请求量不少于 10 次,并且异常比例不低于 0.4(或异常数不少于2),则触发熔断,熔断时长为 5 秒。然后进入 half-open 状态,放行一次请求做测试
授权规则
授权规则可以对调用方的来源做控制,有白名单和黑名单两种方式
白名单:来源(origin)在白名单内的调用者允许访问
黑名单:来源(origin)在黑名单内的调用者不允许访问
在控制台中可以选择新增授权规则,此时就可以选择黑名单或白名单两种方式


Sentinel 是通过 RequestOriginParser 接口中的 parseOrigin() 方法来获取请求的来源的
public interface RequestOriginParser {/*** 从请求request对象中获取origin,获取方式自定义*/String parseOrigin(HttpServletRequest request);
}
但是,默认情况下,这个方法的返回值永远是 “default”。也就是说,Sentinel 默认无法区分所有的请求。因此,我们需要自己实现这个接口,并且编写业务逻辑
案例:
限定只允许从网关发来的请求来访问 service1
实现步骤如下:
1.编写类,实现 RequestOriginParser 接口并编写 parseOrigin() 方法,从 HTTP 请求中获取名为 origin 的请求头并返回
@Component
public class HeaderOriginParser implements RequestOriginParser {@Overridepublic String parseOrigin(HttpServletRequest httpServletRequest) {String origin = httpServletRequest.getHeader("origin");if(StringUtils.isEmpty(origin)) {origin = "blank";}System.out.println(origin);return origin;}
}
2.在 gateway 网关服务中,利用过滤器添加 origin 请求头,值为 gateway
server:port: 10010 # 网关端口
spring:application:name: gateway # 服务名称cloud:gateway:routes: # 网关路由配置- id: service1uri: http://localhost:8081 # 路由的目标地址predicates: # 路由断言,判断请求是否符合路由规则的条件- Path=/service1/** # 路径断言default-filters:- AddRequestHeader=origin,gateway # 添加名为origin的请求头,值为gateway
3.在控制台中配置授权规则

4.测试
首先直接跨过网关访问 service1,如下图所示,可以发现访问失败

然后,通过网关来访问 service1,如下图所示,可以发现访问成功

自定义异常结果
默认情况下,发生限流、降级、授权拦截时,都会抛出异常到调用方。如果要自定义异常时的返回结果,需要实现 BlockExceptionHandler 接口
public interface BlockExceptionHandler {/*** 处理请求被限流、降级、授权拦截时抛出的异常:BlockException*/void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception;
;}
可以看到,handle() 方法中有一个类型为 BlockException 的参数,这个参数表示了具体的异常,而 BlockException 包含很多个子类,分别对应不同的场景,如下所示
| 异常 | 说明 |
|---|---|
| FlowException | 限流异常 |
| ParamFlowException | 热点参数限流的异常 |
| DegradeException | 降级异常 |
| AuthorityException | 授权规则异常 |
| SystemBlockException | 系统规则异常 |
实现自定义异常返回结果的具体方式是,定义一个类,实现 BlockExceptionHandler 接口,然后编写业务逻辑,如下所示:
@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {String msg = "未知异常";int status = 429;if (e instanceof FlowException) {msg = "请求被限流了";} else if (e instanceof ParamFlowException) {msg = "请求被热点参数限流";} else if (e instanceof DegradeException) {msg = "请求被降级了";} else if (e instanceof AuthorityException) {msg = "没有权限访问";status = 401;}response.setContentType("application/json;charset=utf-8");response.setStatus(status);response.getWriter().println("{\"msg\": " + msg + ", \"status\": " + status + "}");}
}
然后进行测试。先在控制台创建流控规则,将 QPS 设为1,如下

然后快速刷新浏览器,结果如下所示,可以看出异常结果和代码所展现的一致

其他的测试也是类似的,但是发现热点规则无法触发该逻辑,用 debug 设置断点发现在异常时没有进入到对应的代码里
因此建议对于热点规则的异常,直接使用全局异常处理即可,如下所示:
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(ParamFlowException.class)public void handleParamFlowException(HttpServletRequest request, HttpServletResponse response, Exception e)throws IOException {response.setContentType("application/json;Charset=utf-8");response.setStatus(429);response.getWriter().println("{\"msg\": " + "请求被热点参数限流" + ", \"status\": " + 429 + "}");}}
测试后发现异常结果可以正常显示

相关文章:
Sentinel隔离、降级、授权规则详解
文章目录 Feign整合Sentinel线程隔离熔断降级授权规则自定义异常结果 上一期教程讲解了 Sentinel 的限流规则: Sentinel限流规则,这一期主要讲述 Sentinel 的 隔离、降级和授权规则 虽然限流可以尽量避免因高并发而引起的服务故障,但服务还…...
C++11 列表初始化与类型声明
目录 0.前言 1.C11介绍 2.统一的列表初始化 2.1{}初始化 2.2initializer_list 2.2.1initializer_list 的基本用法 2.2.2用于类的 initializer_list 构造函数 2.2.3与标准库容器的结合 2.2.4优势与注意事项 3.新声明 3.1auto 3.1.1基本用法 3.1.2优势 3.1.3注意事项 3.2declt…...
缓存策略自定义:Laravel应用性能优化秘籍
缓存策略自定义:Laravel应用性能优化秘籍 在现代Web应用中,缓存是一种提高应用性能和响应速度的有效手段。Laravel框架提供了强大的缓存机制,支持多种缓存驱动,如文件、数据库、Redis等。然而,在某些情况下࿰…...
python连接sqlserver,封装操作
1封装 # 导入Flask类 import pymssql import tracebackclass Mssql(object):# 连接库def base(database):connect pymssql.connect(usersa,password123456,databasef{database},charsetutf8,as_dictTrue)if connect:print("数据库连接成功!")else:print…...
原生PHP/JS自主开发的交友内核框架婚恋交友系统V10
本文来自:婚恋交友系统V10 - 源码1688 应用介绍 原生PHP/JS自主开发的交友内核框架,极高性能、无捆绑、自主权、无流水扣点、独立全开源 01脱单盲盒:脱单盲盒类似于漂流瓶,先将自己《投放》到盲盒中,另一伴有缘将您取…...
如何在Java、Python、GO程序中使用AI人脸识别API接口
AI人脸识别是一种通过面部识别或确认一个人身份的软件。它通过识别和测量图像中的面部特征来工作。面部识别可以识别图像或视频中的人脸,确定两幅图像中的人脸是否属于同一个人,或者在大量现有图像中搜索人脸。 AI人脸识别的优势是什么? 高…...
在vue使用MQTT
在vue中使用MQTT 最近有个需求,需要前端直接链接mqtt,想到后面可能多出使用,就封装成了hooks 中间遇到了一个坑,就是浏览器默认不支持mqtt协议,其借助了webSocket实现的mqtt协议, 而mqtt默认未开启webSocke…...
DNS、网关、IP、DHCP
DNS、网关、IP、DHCP:深入剖析与理解 在计算机网络的世界中,DNS、网关、IP和DHCP是四个至关重要的概念,它们共同构建了互联网的基础架构,确保了数据的准确传输和设备的有效连接。本文将深入剖析这四个概念,帮助读者更…...
vue2 vue3 props 的处理机制
在 Vue 2 中,props 是单向数据流,父组件向子组件传递的 props 默认情况下是不具有响应式特性的。这意味着当父组件的数据发生变化时,如果传递给子组件的 props 发生变化,子组件不会自动更新视图。 具体来说,在 Vue 2 …...
C++第十弹 ---- vector的介绍及使用
目录 前言vector的介绍及使用1. vector的使用1.1 vector的定义1.2 iterator的使用1.3 vector空间增长问题1.4 vector增删查改 2. vector迭代器失效问题(重点) 总结 前言 本文介绍了C中的vector数据结构及其使用方法。 更多好文, 持续关注 ~ 酷酷学!!! 正文开始 vector的介绍…...
ValueError: invalid literal for int() with base 10: ‘a‘
ValueError: invalid literal for int() with base 10: ‘a‘ 目录 ValueError: invalid literal for int() with base 10: ‘a‘ 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰ÿ…...
[C++探索]初始化列表,static成员,友元函数,内部类,匿名对象
💖💖💖欢迎来到我的博客,我是anmory💖💖💖 又和大家见面了 欢迎来到C探索系列 作为一个程序员你不能不掌握的知识 先来自我推荐一波 个人网站欢迎访问以及捐款 推荐阅读 如何低成本搭建个人网站…...
搭建自己的金融数据源和量化分析平台(二):读取上交所股票列表
我在上交所没发现上交所有像深交所一样的一键下载股票xls文档的按钮,因此上交所的股票列表读取就会比较麻烦。总体思路是查出来所有股票的代码之后根据股票代码逐一发起HTTP请求读取公司英文名、总股本、流通股本等详细信息,这就导致上交所爬虫的网络交互…...
Kafka知识总结(分区机制+压缩机制+拦截器+副本机制)
文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 分区机制 分区策略 分区策略是决定生产者将消息发送到哪个分区的…...
WordPress原创插件:搜索引擎抓取首图seo图片
WordPress原创插件:搜索引擎抓取首图seo图片 插件设置 插件将在网站头部添加适当的meta标签,以便百度等搜索引擎抓取指定的固定图像。 插件下载 https://download.csdn.net/download/huayula/89596527...
Android Framework 之AMS
它管理了系统的四大组件:Activity、Service、ContentProvider、Broadcast。 它除了管理四大组件外,同时也负责管理和调度所有的进程 AMS相关目录结构 AMS代码主要在下面几个目录(AndroidQ上AMS相关部分功能移到了wm下): frameworks/base/core/java/andro…...
AnConda环境配置学习笔记
AnConda环境配置 个人笔记,自己学习使用。 1、软件安装 去官网或者是清华大学镜像下载 2、环境配置 Conda 查看版本:conda --version 更新所有库 conda update --all(千万不要跟新,版本不匹配) matploitlib安装cond…...
架构师的36项修炼 学习笔记
架构师的36项修炼 学习笔记 分布式缓存 缓存特点 1.技术简单 2.性能提升明显 3.应用场景多 缓存数据存储 hash表 缓存的关键指标 命中率 缓存失效方式 超时失效 LLT 实时清除 代理缓存 反向代理缓存 多层反向代理缓存 内容分发网络CDN 通读缓存 包括代理缓存…...
Python | “IndexError: tuple index out of range” 【已解决】
Python | “IndexError: tuple index out of range” 【已解决】 IndexError: tuple index out of range 深度解析与实战指南 在Python编程中,IndexError: tuple index out of range是一个常见的错误,它发生在尝试访问元组(或其他可索引的数…...
Linux上部署easySpider及基本使用
一、安装及简介 默认使用Chrome浏览器。 1、下载压缩包 官网:易采集EasySpider:无代码可视化爬虫/浏览器自动化测试软件 Linux版只适用于Ubuntu 20.04及以上版本、Deepin、Debian及其衍生版本。 (建议使用)下载网址/Github下…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
