当前位置: 首页 > news >正文

编码技巧——Sentinel的blockHandler与fallback

本文介绍Sentinel的blockHandler与fallback的区别,背景是:发生限流时,配置的sentinel的blockhandler没有生效而fallback生效了;排查原因,从而给出Sentinel配置异常降级和限流降级的代码写法;

在查看源码前,查阅了相关的技术帖子(1. Sentinel的blockHandler与fallback的区别 2.Sentinel服务熔断[fallBack/blockHandler]),针对同时配置fallback和blockHandler的场景,其中的结论存在不一致,所以决定自己亲手实践下;

1. 未配置fallback和blockHandler

代码如下,仅配置SentinelResource的value,并去sentinel控制台配置单机限流为1;

限流方法:

    /*** 测试sentinel的降级方法*/@SentinelResource(value = "testSentinelFallback")public String testSentinelFallback() {return "返回成功ok";}

测试代码:

    @Overridepublic String mock() {// 异步调用 模拟并发情况for (int i = 0; i < 5; i++) {CompletableFuture.runAsync(() -> {try {final String result = testSentinelService.testSentinelFallback();log.info("调用返回结果 [result={}]", result);} catch (Throwable e) {log.warn("调用抛出异常", e);}});}return null;}

sentinel后台配置:

执行结果:

调用返回结果 [result=返回成功ok]调用抛出异常
java.lang.reflect.UndeclaredThrowableException: null
Caused by: com.alibaba.csp.sentinel.slots.block.flow.FlowException: null调用抛出异常
java.lang.reflect.UndeclaredThrowableException: null
Caused by: com.alibaba.csp.sentinel.slots.block.flow.FlowException: null
...

2. 仅配置blockHandler

2.1 配置blockHandler时未带上额外参数BlockException
    @SentinelResource(value = "testSentinelFallback", blockHandler = "myBlockHandler")public String testSentinelFallback() {return "返回成功ok";}public String myBlockHandler() {return "进入myBlockHandler逻辑";}

执行结果:未进入限流降级方法

调用返回结果 [result=返回成功ok]调用抛出异常
java.lang.reflect.UndeclaredThrowableException: null
Caused by: com.alibaba.csp.sentinel.slots.block.flow.FlowException: null调用抛出异常
java.lang.reflect.UndeclaredThrowableException: null
Caused by: com.alibaba.csp.sentinel.slots.block.flow.FlowException: null
...
2.2 正确的配置blockHandler
    @SentinelResource(value = "testSentinelFallback", blockHandler = "myBlockHandler")public String testSentinelFallback() {return "返回成功ok";}public String myBlockHandler(BlockException blockException) {return "进入myBlockHandler逻辑";}

执行结果:成功进入限流降级方法

调用返回结果 [result=返回成功ok]调用返回结果 [result=进入myBlockHandler逻辑]调用返回结果 [result=进入myBlockHandler逻辑]
...
2.3 blockHandler能捕获业务异常
    @SentinelResource(value = "testSentinelFallback", blockHandler = "myBlockHandler")public String testSentinelFallback() {if (Boolean.TRUE) {throw new BusinessException(FacadeResultCodeEnum.BAD_PARAMS);}return "返回成功ok";}public String myBlockHandler(BlockException blockException) {return "进入myBlockHandler逻辑";}

执行结果:接口被限流时,成功进入限流降级方法;接口出现业务异常时,会抛到外层

调用抛出异常
BusinessException调用返回结果 [result=进入myBlockHandler逻辑]调用返回结果 [result=进入myBlockHandler逻辑]
...

3. 仅配置fallback

3.1 配置fallback时未带上额外参数Throwable
    @SentinelResource(value = "testSentinelFallback", fallback = "myFallback")public String testSentinelFallback() {if (Boolean.TRUE) {throw new BusinessException(FacadeResultCodeEnum.BAD_PARAMS);}return "返回成功ok";}public String myFallback() {return "进入myFallback逻辑";}

执行结果:接口被限流时,或者接口出现业务异常时,都会进入fallback降级方法

调用返回结果 [result=进入myFallback逻辑]调用返回结果 [result=进入myFallback逻辑]调用返回结果 [result=进入myFallback逻辑]
...

3.2 配置fallback时带上额外参数Throwable

    @SentinelResource(value = "testSentinelFallback", fallback = "myFallback")public String testSentinelFallback() {if (Boolean.TRUE) {throw new BusinessException(FacadeResultCodeEnum.BAD_PARAMS);}return "返回成功ok";}public String myFallback(Throwable throwable) {if (throwable instanceof BlockException) {return "进入myFallback逻辑 限流异常";}return "进入myFallback逻辑 业务异常";}

执行结果:接口被限流时,或者接口出现业务异常时,都会进入fallback降级方法;且可以通过异常类型区分出限流异常和业务异常

调用返回结果 [result=进入myFallback逻辑 业务异常]调用返回结果 [result=进入myFallback逻辑 限流异常]
调用返回结果 [result=进入myFallback逻辑 限流异常]
...

4. 同时配置fallback和blockHandler

    @SentinelResource(value = "testSentinelFallback", fallback = "myFallback", blockHandler = "myBlockHandler")public String testSentinelFallback() {if (Boolean.TRUE) {throw new BusinessException(FacadeResultCodeEnum.BAD_PARAMS);}return "返回成功ok";}public String myFallback(Throwable throwable) {if (throwable instanceof BlockException) {return "进入myFallback逻辑 限流异常";}return "进入myFallback逻辑 业务异常";}public String myBlockHandler(BlockException blockException) {return "进入myBlockHandler逻辑";}

执行结果:若blockHandler和fallback都进行了配置,在未触发限流进入到方法逻辑抛出业务异常时,会进入fallback方法在触发限流时,进入不到方法逻辑,直接抛出BlockException进入blockHandler方法

5. 结论

5.1 异常捕获逻辑

1. blockHandler

  • blockHandler仅处理限流异常;
  • 使用blockHandler时,方法签名参数与原方法一致,且必须要在参数的最后位置补充BlockException参数;
  • 若未补充BlockException参数则不生效;

2. fallback

  • fallback可以处理所有类型异常,包括限流异常和业务异常;
  • 使用fallback时,方法签名参数可以与原方法完全一致,或者也接受在参数的最后位置补充Throwable参数;
  • 通过对Throwable参数的类型区分是限流异常还是其他异常;
  • 当同时生效blockHandler和fallback时,限流异常会优先被blockHandler处理而不再进入fallback逻辑;
5.2 合理的代码写法

(1)同时配置生效blockHandler和fallback分别处理限流异常和业务异常

    @SentinelResource(value = "testSentinelFallback", fallback = "myFallback", blockHandler = "myBlockHandler")public String testSentinelFallback() {// ...return "返回成功ok";}public String myFallback(Throwable throwable) {return "进入myFallback逻辑 业务异常";}public String myBlockHandler(BlockException blockException) {return "进入myBlockHandler逻辑";}

(2)仅配置fallback并通过Throwable类型区分限流异常和业务异常

    @SentinelResource(value = "testSentinelFallback", fallback = "myFallback")public String testSentinelFallback() {// ...return "返回成功ok";}public String myFallback(Throwable throwable) {if (throwable instanceof com.alibaba.csp.sentinel.slots.block.flow.FlowException) {final FlowRule rule = ((FlowException) throwable).getRule();final double count = rule.getCount();final String resource = rule.getResource();// 打印限流规则信息log.warn("testSentinelFallback触发限流降级 [sentinelResource={} QpsLimit={}]]", resource, count);return null;} else {log.warn("testSentinelFallback触发异常降级 抛出异常", throwable);throw new RuntimeException("testSentinelFallback业务异常");}}
5.3 注解参数释义及注意事项

1. @SentinelResource注解参数说明

属性默认值说明
blockHandler

用于在抛出限流/熔断/系统保护等异常的降级处理逻辑,blockHandler 针对BlockException类型的异常,优先级比fallback高

blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException;

blockHandler 函数默认需要和原方法在同一个类中;

blockHandlerClass若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析;
defaultFallback默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法);

默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理;

若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效

entryTypeEntryType.OUT资源调用的流量类型,是入口流量(EntryType.IN)还是出口流量(EntryType.OUT),注意系统保护规则只对 IN 生效
exceptionsToIgnore用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出; 优先级高于exceptionsToTrace
exceptionsToTraceThrowable.class用于指定哪些异常不被排除掉;如果属于该类型,则会计入异常统计中,也会进入 fallback 逻辑中,不会原样抛出;不建议修改默认值;
fallback

用于在抛出异常的时候提供 fallback 处理逻辑;fallback 针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)

方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常(注意和blockHandler添加的BlockException不一样)

fallbackClass类似blockHandlerClass参数
resourceType资源类型,默认0
value资源名称,必需项

2. 区分限流异常和熔断异常

限流状态会抛异常:FlowException(继承BlockException)

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.alibaba.csp.sentinel.slots.block.flow.FlowException] with root causecom.alibaba.csp.sentinel.slots.block.flow.FlowException: null

熔断状态会抛异常:DegradeException(继承BlockException)

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.alibaba.csp.sentinel.slots.block.degrade.DegradeException] with root causecom.alibaba.csp.sentinel.slots.block.degrade.DegradeException: null

 

参考:annotation-support | Sentinel

相关文章:

编码技巧——Sentinel的blockHandler与fallback

本文介绍Sentinel的blockHandler与fallback的区别&#xff0c;背景是&#xff1a;发生限流时&#xff0c;配置的sentinel的blockhandler没有生效而fallback生效了&#xff1b;排查原因&#xff0c;从而给出Sentinel配置异常降级和限流降级的代码写法&#xff1b; 在查看源码前…...

最新成果展示:GaN基Micro-LED热学模型数据库的开发及应用

由于GaN基Micro-LED表面积-体积比增加&#xff0c;其在热学方面的性质有别于大尺寸的LED&#xff0c;如缺陷复合导致的热效应将在发光区域中产生诸多“热”点&#xff0c;导致发光波长不均匀&#xff0c;这将影响后期显示系统的成像稳定性。针对上述问题&#xff0c;天津赛米卡…...

【Vue3】动态组件

动态组件的基本使用 动态组件&#xff08;Dynamic Components&#xff09;是一种在 Vue 中根据条件或用户输入来动态渲染不同组件的技术。 在 Vue 中使用动态组件&#xff0c;可以使用 元素&#xff0c;并通过 is 特性绑定一个组件的名称或组件对象。通过在父组件中改变 is 特…...

Java超级玛丽小游戏制作过程讲解 第五天 创建并完成常量类04

//加载障碍物 try {obstacle.add(ImageIO.read(new File(path"brick.png")));obstacle.add(ImageIO.read(new File(path"soil_up.png")));obstacle.add(ImageIO.read(new File(path"soil_base.png"))); } catch (IOException e) {e.printStackTr…...

设置浏览器兼容

浏览器兼容 css兼容 cursor定义手型  Firefox不支持hand&#xff0c;IE支持pointer  解决方法&#xff1a;统一使用pointercss透明  IE&#xff1a;filter:progid:DXImageTransform.Microsoft.Alpha(style0,opacity60)  Firefox&#xff1a;opacity&#xff1a;0.6  解决…...

Java # List

ArrayList<>() import java.util.ArrayList; // 引入 ArrayList 类ArrayList<E> objectName new ArrayList<>();  // 初始化 常用方法 方法描述add()将元素插入到指定位置的 arraylist 中addAll()添加集合中的所有元素到 arraylist 中clear()删除 arrayl…...

git原理与使用

目录 引入基本操作分支管理远程操作标签管理 引入 假设你的老板要你设计一个文档&#xff0c;当你设计好了&#xff0c;拿给他看时&#xff0c;他并不是很满意&#xff0c;就要你拿回去修改&#xff0c;你修改完后&#xff0c;再给他看时&#xff0c;他还是不满意&#xff0c;…...

【C语言题解】将一句话的单词进行倒置,标点不倒置。

题目描述&#xff1a;将一句话的单词进行倒置&#xff0c;标点不倒置。比如 “I like beijing.”&#xff0c;经过处理后变为&#xff1a;“beijing. like I”。 文章目录 原题目题目描述&#xff1a;输入描述&#xff1a;输出描述&#xff1a;题目链接&#xff1a; 整体思路分…...

Postman 的简单使用

什么是Postman 在程序开发中用于调试网络程序或者跟踪网页请求。可以对网页进行简单的基本信息调试。Postman最早是作用chrome浏览器插件存在的&#xff0c;但是2018年初Chrome停止对Chrome应用程序的支持。所以现在Postman提供了独立的安装包&#xff0c;不再依赖于Chrome浏览…...

在CentOS7安装部署GitLab服务

CentOS 7 安装 Gitlab 官方安装教程&#xff1a;https://about.gitlab.com/install/ 参考安装教程&#xff1a;https://developer.aliyun.com/article/74395 安装配置 Step1&#xff1a;配置yum源 vim /etc/yum.repos.d/gitlab-ce.repo存入以下内容&#xff1a; [gitlab-c…...

订单系统就该这么设计,稳的一批~

订单功能作为电商系统的核心功能&#xff0c;由于它同时涉及到前台商城和后台管理系统&#xff0c;它的设计可谓是非常重要的。就算不是电商系统中&#xff0c;只要是涉及到需要交易的项目&#xff0c;订单功能都具有很好的参考价值&#xff0c;说它是通用业务功能也不为过。今…...

Agents改变游戏规则,亚马逊云科技生成式AI让基础模型加速工作流

最近&#xff0c;Stability AI正式发布了下一代文生图模型——Stable Diffusion XL 1.0这次的1.0版本是Stability AI的旗舰版生图模型&#xff0c;也是最先进的开源生图模型。 在目前的开放式图像模型中&#xff0c;SDXL 1.0是参数数量最多的。官方表示&#xff0c;这次采用的…...

详细教程:如何搭建废品回收小程序

废品回收是一项环保举措&#xff0c;通过回收和再利用废弃物品&#xff0c;可以减少资源浪费和环境污染。近年来&#xff0c;随着智能手机的普及&#xff0c;小程序成为了推广和运营的重要工具。本文将详细介绍如何搭建一个废品回收小程序。 1. 进入乔拓云网后台 首先&#xf…...

什么是双亲委派机制?

什么是双亲委派机制&#xff1f; Parent Delegation Model &#xff0c;直译过来可能叫做父级委托模型更容易理解 类的加载过程 Java 编译器将 Java源文件编译成.class 文件再由 JVM 加载 .class 文件到内存中JVM 装载完成后得到一个 Class 字节码对象拿到字节码对象之后 &a…...

Mageia 9 RC1 正式发布,Mandriva Linux 发行版的社区分支

导读Mageia 9 首个 RC 已发布。公告写道&#xff0c;自 2023 年 5 月发布 beta 2 以来&#xff0c;Mageia 团队一直致力于解决许多顽固问题并提供安全修复和新特性。 新版本的控制中心添加了用于删除旧内核的新功能&#xff0c;该功能在 Mageia 9 中默认自动启用&#xff0c;用…...

ChatGPT: 人机交互的未来

ChatGPT: 人机交互的未来 ChatGPT背景ChatGPT的特点ChatGPT的应用场景结论 ChatGPT ChatGPT是一种基于大数据和机器学习的人工智能聊天机器人模型。它由国内团队发明、开发&#xff0c;并被命名为Mental AI。ChatGPT的目标是通过模拟自然对话的方式&#xff0c;提供高效、智能…...

Linux 常用操作命令

Linux简介及Ubuntu安装 Linux&#xff0c;免费开源&#xff0c;多用户多任务系统。基于Linux有多个版本的衍生。RedHat、Ubuntu、Debian 安装VMware或VirtualBox虚拟机。具体安装步骤&#xff0c;找百度。 再安装Ubuntu。具体安装步骤&#xff0c;找百度。 常用指令 ls  …...

24届近5年重庆邮电大学自动化考研院校分析

今天给大家带来的是重庆邮电大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、重庆邮电大学 学校简介 重庆邮电大学简称"重邮"&#xff0c;坐落于直辖市-重庆市&#xff0c;入选国家"中西部高校基础能力建设工程”、国家“卓越工程师教育培养计划…...

如何对oracle和mysql进行 分区分表

前提&#xff1a;使用自带的分区和分表机制进行操作 oracle,mysql分区分表 分区 分区是一种将一个大的表或索引分割成多个小的部分的技术&#xff0c;每个部分称为一个分区。分区可以提高数据的管理和查询效率&#xff0c;因为可以根据不同的条件对不同的分区进行操作&#x…...

Windows下安装Sqoop

Windows下安装Sqoop 一、Sqoop简介二、Sqoop安装2.1、Sqoop官网下载2.2、Sqoop网盘下载2.3、Sqoop安装&#xff08;以version&#xff1a;1.4.7为例&#xff09;2.3.1、解压安装包到 D:\bigdata\sqoop\1.4.7 目录2.3.2、新增环境变量 SQOOP_HOME2.3.3、环境变量 Path 添加 %SQO…...

腾讯云秒杀活动是什么?2026年最新参与指南(附抢购技巧)

腾讯云秒杀活动是什么&#xff1f;怎么参与&#xff1f;本文将详细解析腾讯云秒杀活动规则、参与入口、抢购技巧及备选方案&#xff0c;助力大家低成本开启云端之旅&#xff01; 一、活动介绍 腾讯云秒杀活动是腾讯云官方推出的限量限时抢购活动&#xff0c;主打高性价比的轻量…...

Linux网络运维实战:从ifconfig、ethtool到网络状态深度诊断

1. 从ifconfig开始&#xff1a;你的网络诊断第一课 刚接手一台Linux服务器时&#xff0c;我习惯性敲下的第一个命令永远是ifconfig。这个看似简单的命令就像汽车仪表盘&#xff0c;能快速告诉你当前网络接口的基本状态。记得有次凌晨处理线上故障&#xff0c;就是通过ifconfig…...

BES平台音频算法集成避坑指南:从声加ENC案例看副核调度与内存优化

BES平台音频算法深度优化&#xff1a;从ENC案例剖析多核调度与内存管理 在蓝牙音频芯片领域&#xff0c;BES平台凭借其出色的能效比和灵活的架构设计&#xff0c;已成为众多高端TWS耳机厂商的首选方案。然而&#xff0c;当工程师们尝试将ENC&#xff08;环境噪声消除&#xff0…...

Steam-Economy-Enhancer多货币支持:全球交易定价策略

Steam-Economy-Enhancer多货币支持&#xff1a;全球交易定价策略 【免费下载链接】Steam-Economy-Enhancer Enhances the Steam Inventory and Steam Market. 项目地址: https://gitcode.com/gh_mirrors/st/Steam-Economy-Enhancer Steam-Economy-Enhancer是一款强大的S…...

MATLAB bandpass函数实战:用音乐合成和滤波案例,5分钟搞懂信号处理核心参数

MATLAB bandpass函数实战&#xff1a;从音乐合成到精准滤波的完整指南 1. 用MATLAB合成你的第一段数字音乐 在开始滤波之前&#xff0c;让我们先创造一段属于自己的数字音乐。这个过程中&#xff0c;你会理解声音信号在数字世界中的本质——它不过是一串随时间变化的数字序列。…...

三步搞定Windows磁盘空间不足:WinDirStat终极清理方案

三步搞定Windows磁盘空间不足&#xff1a;WinDirStat终极清理方案 【免费下载链接】windirstat WinDirStat is a disk usage statistics viewer and cleanup tool for Microsoft Windows 项目地址: https://gitcode.com/gh_mirrors/wi/windirstat 你是否经常遇到Windows…...

代码即文档:让三个月后的自己还能看懂今天写的逻辑

在软件测试领域&#xff0c;我们擅长用精密的逻辑去验证他人的代码&#xff0c;却常常在一个隐蔽的角落跌倒——我们自己写的测试代码。三个月前&#xff0c;你精心构建了一套自动化测试框架&#xff0c;一个周末&#xff0c;数百行代码&#xff0c;逻辑环环相扣&#xff0c;运…...

如何高效配置Cool Request插件:Spring Boot接口调试的终极实践指南

如何高效配置Cool Request插件&#xff1a;Spring Boot接口调试的终极实践指南 【免费下载链接】cool-request IDEA API、Java Method debug tools 项目地址: https://gitcode.com/gh_mirrors/co/cool-request Cool Request是一款专为IntelliJ IDEA设计的强大HTTP接口调…...

学校AIGC检测标准差异解读:不同高校AI率标准对比2026年如何针对性免费处理完整指南

学校AIGC检测标准差异解读&#xff1a;不同高校AI率标准对比2026年如何针对性免费处理完整指南 同一段文字&#xff0c;不同平台检测AI率相差20%以上。这不是玄学&#xff0c;有原因可解释。 关于高校AIGC检测标准差异解读&#xff0c;理解了背后逻辑&#xff0c;很多「奇怪现…...

Linux服务器安全基线自动化实践:基于Ansible的加固方案

1. 项目概述与核心价值“安全加固”这个词&#xff0c;对于任何一个负责线上系统运维、应用部署或者个人服务器管理的朋友来说&#xff0c;都绝不陌生。它就像给自家房子装防盗门、安监控一样&#xff0c;是基础且必要的工作。然而&#xff0c;现实情况往往是&#xff1a;我们面…...