一、Sentinel 资源异常处理的 3 级优先级规则
针对 @SentinelResource 标注的资源,异常处理按以下顺序生效(优先级从高到低):
- blockHandler :仅处理 Sentinel 规则触发的异常 (如限流、熔断、授权拦截),对应
BlockException及其子类; - fallback :处理 业务异常 (如空指针、远程调用失败),也可兼容处理
BlockException; - defaultFallback:全局兜底处理器,未被前两者捕获的所有异常都会进入这里;
- 若三者都未配置:直接抛出异常到上层(如控制器,也就是Springboot默认的控制器的异常)。
二、基于代码的配置示例(以createOrder资源为例)
1. 服务层:配置 3 级处理器
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private ProductFeignClient productFeignClient;
// 核心:配置blockHandler、fallback、defaultFallback
@SentinelResource(
value = "createOrder",
blockHandler = "createOrderBlockHandler", // 1. 限流/熔断兜底
fallback = "createOrderFallback", // 2. 业务异常兜底
defaultFallback = "createOrderDefaultFallback" // 3. 全局兜底
)
@Override
public Order createOrder(Long productId, Long userId) {
// 1. Feign远程调用(可能触发业务异常)
Product product = productFeignClient.getProductById(productId);
if (product == null) {
throw new RuntimeException("商品不存在"); // 模拟业务异常
}
// 2. 业务逻辑(可能触发Sentinel规则)
Order order = new Order();
order.setId(1L);
order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));
order.setUserId(userId);
order.setNickName("zhangsan");
order.setAddress("尚硅谷");
order.setProductList(Arrays.asList(product));
return order;
}
// 1. blockHandler:仅处理BlockException(限流/熔断)
public Order createOrderBlockHandler(Long productId, Long userId, BlockException e) {
Order order = new Order();
order.setId(0L);
order.setAddress("限流/熔断拦截:" + e.getClass().getSimpleName());
return order;
}
// 2. fallback:处理业务异常(也可加BlockException参数兼容处理)
public Order createOrderFallback(Long productId, Long userId, Throwable e) {
Order order = new Order();
order.setId(0L);
order.setAddress("业务异常:" + e.getMessage());
return order;
}
// 3. defaultFallback:全局兜底(无方法参数,仅Throwable)
public Order createOrderDefaultFallback(Throwable e) {
Order order = new Order();
order.setId(0L);
order.setAddress("全局兜底:" + e.getClass().getSimpleName());
return order;
}
}
2. 控制器层:无需额外处理(异常已被服务层兜底)
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
// 前端请求直接调用,服务层已通过Sentinel完成异常兜底
@GetMapping("/create")
public Order createOrder(
@RequestParam("userId") Long userId,
@RequestParam("productId") Long productId
) {
return orderService.createOrder(productId, userId);
}
}
三、关键注意事项
- 方法签名规则:
-
blockHandler:必须和原方法参数一致 ,最后加BlockException参数;fallback:必须和原方法参数一致 ,最后加Throwable参数;defaultFallback:无原方法参数 ,仅需Throwable参数。
- 方法访问权限 :处理器方法(如
createOrderBlockHandler)必须是public且和原方法在同一个类中 (或通过blockHandlerClass指定外部类)。 - 异常覆盖范围:
blockHandler 仅管 Sentinel 规则异常;
fallback 管业务异常,也可通过加 BlockException 参数同时管规则异常;
defaultFallback 是最终兜底。