目录
sentinel-异常处理-@SentinelResource
[二、@SentinelResource 核心属性(异常处理重点)](#二、@SentinelResource 核心属性(异常处理重点))
[1. 前置准备](#1. 前置准备)
[2. 基础使用:配置 blockHandler(处理限流 / 熔断异常)](#2. 基础使用:配置 blockHandler(处理限流 / 熔断异常))
[sentinel-异常处理-SphU 硬编码](#sentinel-异常处理-SphU 硬编码)
Sentinel-基础-工作原理
功能介绍
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。SpringcloudAlibabasentinel以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应过载保护、热点流量防护等多个维度保护服务的稳定性。

架构原理

资源&规则
定义资源:
- 主流框架自动适配(Web Servlet、Dubbo、Spring Cloud、gRPC、Spring WebFlux、Reactor);
- 所有Web接口均为资源
- 编程式:SphUAPI
- 声明式:@SentinelResource
定义规则:
- 流量控制(FlowRule)
- 熔断降级(DegradeRule)
- 系统保护(SystemRule)
- 来源访问控制(AuthorityRule)
- 热点参数(ParamFlowRule)
工作原理

Sentinel-整合-基础场景
整合使用

下载sentinel控制台:https://github.com/alibaba/Sentinel/releases/tag/1.8.8
下载完成之后,在路径中输入cmd,然后输入
java -jar sentinel-dashboard-1.8.8.jar
如下图所示,sentinel启动成功:

启动成功之后,访问Sentinel Dashboard,账号密码都是sentinel:

登录成功页面如下:

在services的pom文件中引入sentinel依赖:
<!-- 导入sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
引入完成之后,每一个微服务都需要配置连接上sentinel控制台:
订单服务:在配置文件中添加:
sentinel:
transport:
dashboard: locallhost:8080
eager: true
商品服务:
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.eager=true
重启服务,刷新sentinel控制台,发现控制台中已有order-service和product-service。

定义资源
1.假设在订单服务中,我们认为createOrder是一个资源,一个最简单的方法就是在该方法上面添加
@SentinelResource(value = "createOrder")注解。
2.重启订单服务。
3.在前端发送createOrder请求:http://localhost:8000/create?userId=2&productId=4
4.请求返回成功之后,查看sentinel控制台的service的簇点链路。

6.有了这些资源,就可以对这些资源进行流控、熔断、热点、授权的控制。
添加规则
假设对/create添加流控规则

点击新增,在流控规则栏就可以看到添加的规则

重启服务,访问/create,访问请求过快时,则会出现以下错误。
上述现象可以,当访问访问请求过快时,会自动返回提示。接下来看sentinel的异常处理
sentinel-异常处理-Web接口

我们要使当请求违反规则时,返回的数据按照我们想要的方式返回,就需要重写一个异常处理器。首先在service-order中添加一个MyBlockExceptionHandle类。
package com.atguigu.order.exception;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.common.R;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.PrintWriter;
@Component
public class MyBlockExceptionHandle implements BlockExceptionHandler {
/**
* 这是springMVC框架底层整合的jackson,提供的一个json工具
*/
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void handle(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
String s,
BlockException e) throws Exception {
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter writer = httpServletResponse.getWriter();
R error = R.error(s + "被sentinel限制了,原因是:" + e.getMessage());
String json = objectMapper.writeValueAsString(error);
writer.write(json);
}
}
然后我们需要在model下定义一个统一返回结果的类:
package com.atguigu.common;
import lombok.Data;
@Data
public class R {
private String code;
private String message;
private Object data;
public static R ok() {
R r = new R();
r.setCode("200");
r.setMessage("操作成功");
return r;
}
public static R ok(Object data) {
R r = new R();
r.setCode("200");
r.setMessage("操作成功");
r.setData(data);
return r;
}
public static R error() {
R r = new R();
r.setCode("500");
r.setMessage("操作失败");
return r;
}
public static R error(String message) {
R r = new R();
r.setCode("500");
r.setMessage(message);
return r;
}
}
重启项目,多次访问/create,发现返回的是我们想要的格式:

sentinel-异常处理-@SentinelResource
一、核心概念
1.@SentinelResource 是什么?
@SentinelResource 是什么? 它是 Sentinel 提供的注解式资源定义方式 ,用于标记一个「受 Sentinel 保护的资源」(比如一个方法、一个接口)。通过这个注解,你可以脱离 Sentinel 原生的硬编码方式(SphU.entry()/exit()),更优雅地实现资源的限流、熔断、降级,同时还能自定义异常处理逻辑。
2.核心作用(异常处理相关)
- 标记受保护资源,让 Sentinel 能够对该资源进行流量控制和熔断监控。
- 自定义限流 / 熔断后的兜底处理逻辑(而非直接返回 Sentinel 默认的错误页面 / 信息)。
- 区分业务异常 和Sentinel 限流 / 熔断异常,避免二者混淆。
二、@SentinelResource 核心属性(异常处理重点)
注解中有几个核心属性,重点关注和异常处理相关的:
| 属性名 | 作用 | 是否必填 | 备注 |
|---|---|---|---|
value |
资源名称(唯一标识,Sentinel 控制台展示的资源名) | 是 | 必须指定唯一值,用于区分不同资源 |
blockHandler |
限流 / 熔断后的兜底方法名 (处理 Sentinel 定义的 BlockException 及其子类) |
否 | 兜底方法需满足「同参数、同返回值、与原方法在同一个类中」,可额外添加 BlockException 入参 |
blockHandlerClass |
兜底方法所在的类(当兜底方法不在原方法所在类时使用) | 否 | 兜底方法必须是静态方法 ,且满足「同参数、同返回值、可额外加 BlockException 入参」 |
fallback |
处理业务异常 (非 BlockException)的兜底方法名 |
否 | 兜底方法需满足「同返回值、参数列表与原方法一致,或额外添加 Throwable 入参」 |
fallbackClass |
业务异常兜底方法所在的类 | 否 | 兜底方法必须是静态方法 ,规则同 fallback |
exceptionsToIgnore |
需要忽略的异常类型(不触发 fallback) |
否 | 例如 NullPointerException.class,忽略后该异常不会进入 fallback 方法 |
关键区分:BlockException 是 Sentinel 自身抛出的异常(包含限流、熔断、系统保护等场景),只有它会触发 blockHandler ;而普通业务异常(如 NullPointerException、IllegalArgumentException)会触发 fallback(若配置)。
三、实操示例
1. 前置准备
先引入 Sentinel 核心依赖(Spring Boot 项目),确保项目能正常集成 Sentinel:
<!-- Spring Cloud Alibaba Sentinel 核心依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<!-- 版本需与 Spring Cloud Alibaba 版本匹配,例如 2021.0.1.0 -->
<version>2021.0.1.0</version>
</dependency>
2. 基础使用:配置 blockHandler(处理限流 / 熔断异常)
这是最常用的场景,实现「资源被限流 / 熔断后,返回自定义兜底响应」。
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SentinelDemoController {
// 标记受保护资源,配置 blockHandler 兜底方法
@GetMapping("/hello")
@SentinelResource(value = "helloResource", blockHandler = "helloBlockHandler")
public String hello(@RequestParam(required = false, defaultValue = "guest") String name) {
// 正常业务逻辑
return "Hello, " + name + "!";
}
// 限流/熔断兜底方法:满足 同参数、同返回值、额外可加 BlockException
public String helloBlockHandler(String name, BlockException e) {
// 自定义兜底响应,可打印异常信息排查问题
System.err.println("资源【helloResource】被限流/熔断,异常类型:" + e.getClass().getSimpleName());
return "抱歉,当前访问人数过多,请稍后再试!";
}
}
测试方式:
- 启动项目,访问
http://localhost:8080/hello?name=test,正常返回Hello, test!。 - 启动 Sentinel 控制台(需提前下载并启动),在「流量控制规则」中给
helloResource添加一条限流规则(例如:QPS 阈值 = 1,即每秒最多允许 1 次访问)。 - 快速多次访问
http://localhost:8080/hello,触发限流,会返回兜底信息抱歉,当前访问人数过多,请稍后再试!,同时控制台会打印异常类型(FlowException,即限流异常)。
四、关键注意事项
- 兜底方法的签名规则
blockHandler方法:必须与原方法参数列表一致 ,返回值一致,可额外添加BlockException入参(用于获取异常详情)。fallback方法:必须与原方法返回值一致 ,参数列表可一致,或额外添加Throwable入参(用于获取业务异常详情)。- 抽离到单独类时,兜底方法必须是 **
public static** 修饰。
- 异常优先级
- 当方法同时抛出
BlockException和业务异常时,blockHandler优先级高于fallback(即 Sentinel 异常优先处理)。 exceptionsToIgnore配置的异常,不会触发fallback方法,会直接向上抛出。
- 当方法同时抛出
- 资源名唯一性
value属性是资源的唯一标识,Sentinel 控制台的规则配置、监控数据都依赖该名称,建议命名规范(如接口名:方法名)。
- 注解生效条件
- 确保项目中已启用 Sentinel 注解支持(Spring Boot 项目中,引入
spring-cloud-starter-alibaba-sentinel后会自动启用,无需额外配置;非 Spring Boot 项目需手动配置SentinelResourceAspect)。
- 确保项目中已启用 Sentinel 注解支持(Spring Boot 项目中,引入
sentinel-异常处理-openfeign调用
在前面openfeign文章中已讲解。
sentinel-异常处理-SphU 硬编码
这种异常处理的方法就是try-catch方法包围即可。