Sentinel 笔记
1 介绍
Sentinel 是阿里开源的分布式系统流量防卫组件,专注于 流量控制、熔断降级、系统保护。
官网:https://sentinelguard.io/zh-cn/index.html
wiki:https://github.com/alibaba/Sentinel/wiki
对比同类产品:
产品 | 特点 |
---|---|
Hystrix | Netflix 开源,功能全面但已停止维护,基于线程池隔离,资源消耗较大 |
Resilience4j | 轻量级,基于函数式编程,但需要结合其他组件实现完整功能 |
Sentinel | 轻量级,实时监控和控制,支持动态规则配置,与 Spring Cloud 深度集成 |
2 架构
- 核心模块:
- 资源:被保护的代码逻辑(如接口、方法)。
- 规则:流量控制、熔断降级等策略。
- 控制台:可视化规则配置与实时监控。
4 环境搭建
4.1 依赖
<!-- Spring Cloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
4.2 启动控制台
-
下载 Sentinel Dashboard 官方 Release或📎sentinel-dashboard-1.8.8.jar
-
启动命令:
下载完成后:在文件目录输入cmd进入bash命令行
在命令行窗口输入:即可启动项目
java -jar sentinel-dashboard-1.8.8.jar
3.通过http://localhost:8080即可访问sentinel的控制台
正常访问后显示的界面:
4.3 配置连接
在 application.yml
中配置:
# 订单以及商品都要配置
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # 控制台地址
eager: true # 立即初始化
配置成功后:
假设我们要把createOrder注册为我们要管理的服务。
@SentinelResource(value = "createOrder")
public Order createOrder(Long userId, Long productId) {
//Product product = productFeignClient.getProductById(productId);
//使用RestTemplate实现负载均衡
//Product product = getProductFromRemqteWithLoadBalanceAnnotation(productId);
//使用feignClient实现远程调用
Product product = productFeignClient.getProductById(productId);
Order order = new Order();
order.setId(1L);
order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));
//order.setTotalAmount(BigDecimal.valueOf(0));
order.setUserId(userId);
order.setNickName("zhangsan");
order.setAddress("尚硅谷");
order.setProductList(Arrays.asList(product));
return order;
}
创建订单的请求:http://localhost:8000/order/create?userId=1&productId=100
接下来就可以对资源进行流控。
QPS:每秒能接收的请求数
5 异常处理
5.1 自定义 BlockExceptionHandler
目的:处理业务异常,出现异常可以给前端传递一些消息。
实现 BlockExceptionHandler
接口,处理流控/熔断异常:
// order模块下
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
String resourceName, BlockException e) throws Exception {
response.setStatus(429); //too many requests
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
R error = R.error(500, resourceName + " 被Sentinel限制了,原因:" + e.getClass());
String json = objectMapper.writeValueAsString(error);
writer.write(json);
writer.flush();
writer.close();
}
}
5.2 blockHandler
使用 @SentinelResource
注解指定降级方法:
@SentinelResource(value = "createOrder",blockHandler = "createOrderFallback")
@Override
public Order createOrder(Long productId, Long userId) {
// Product product = getProductFromRemoteWithLoadBalanceAnnotation(productId);
//使用Feign完成远程调用
Product product = productFeignClient.getProductById(productId);
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;
}
//出现异常,兜底回调
public Order createOrderFallback(Long productId, Long userId, BlockException e){
Order order = new Order();
order.setId(0L);
order.setTotalAmount(new BigDecimal("0"));
order.setUserId(userId);
order.setNickName("未知用户");
order.setAddress("异常信息:"+e.getClass());
return order;
}
//没自定义异常,就会自动向上抛,最后给Spring的全局拦截器捕获到,由spring去处理异常
5.3 OpenFeign-兜底回调
- 实现 Fallback 类:
@FeignClient(value = "service-product",fallback = ProductFeignClientFallback.class) // feign客户端
public interface ProductFeignClient {
//mvc注解的两套使用逻辑
//1、标注在Controller上,是接受这样的请求
//2、标注在FeignClient上,是发送这样的请求
@GetMapping("/product/{id}")
Product getProductById(@PathVariable("id") Long id);
}
2.在 Feign 接口中指定:
@FeignClient(name = "user-service", fallback = UserServiceFallback.class)
public interface UserService { /* ... */ }
6 规则 - 流量控制
6.1 阈值类型
- QPS:每秒请求数。
- 线程数:并发线程数。
6.2 流控模式
- 直接:针对当前资源。
- 关联:关联资源触发阈值时限流。
- 链路:基于调用链路限流。
6.3 流控效果
- 快速失败:直接拒绝请求。
- Warm Up:预热模式,逐步增加阈值。
- 排队等待:请求进入队列等待处理。
7 规则 - 熔断降级
7.1 断路器状态
- Closed:正常状态。
- Open:熔断状态,拒绝所有请求。
- Half-Open:尝试放行部分请求探测恢复情况。
7.2 工作原理
- 慢调用比例:响应时间超过阈值且比例超限。
- 异常比例:异常比例超限。
- 异常数:异常数超限。
7.3 熔断与兜底
8 规则 - 热点参数
8.1 环境搭建
- 添加热点参数限流规则:
@GetMapping("/seckill")
@SentinelResource(value = "seckill-order",fallback = "seckillFallback")
public Order seckill(@RequestParam(value = "userId",required = false) Long userId,
@RequestParam(value = "productId",defaultValue = "1000") Long productId){
Order order = orderService.createOrder(productId, userId);
order.setId(Long.MAX_VALUE);
return order;
}
public Order seckillFallback(Long userId,Long productId, BlockException exception){
System.out.println("seckillFallback....");
Order order = new Order();
order.setId(productId);
order.setUserId(userId);
order.setAddress("异常信息:"+exception.getClass());
return order;
}
重点总结
- 核心功能:
- 流量控制(QPS/线程数)、熔断降级(慢调用/异常比例)、热点参数限流。
- 优势:
- 动态规则配置,实时监控,与 Spring Cloud 无缝集成。
- 实操关键:
- 控制台启动后需配置
spring.cloud.sentinel.transport.dashboard
。 - 使用
@SentinelResource
定义资源和降级逻辑。 - OpenFeign 需结合 Fallback 类实现服务降级。
- 控制台启动后需配置
- 注意事项:
- 规则配置后需持久化到 Nacos/Redis,避免重启丢失。
- 生产环境建议开启 Sentinel 的集群流控功能。