Spring Cloud Sentinel快速入门步骤

 更新时间:2025年11月25日 10:10:52   作者:ruleslol  
本文介绍了Sentinel,一个用于企业级微服务开发的流量控制、熔断降级和系统负载保护的组件,Sentinel的核心概念包括资源、规则和SlotChain,其三大核心功能分别是流量控制、熔断降级和系统保护,感兴趣的朋友跟随小编一起看看吧

在企业级微服务开发中,Sentinel 解决的是系统稳定性问题。

一、Sentinel 核心概念与目标

Sentinel(分布式系统的流量防卫兵)是阿里巴巴开源的一套面向分布式服务架构的流量控制熔断降级系统负载保护的组件。

它的核心目的是保护应用,确保服务在面对高并发、突发流量或依赖服务不可用时,仍能保持高可用性稳定性,避免因局部故障导致整个系统雪崩。

1-1. 核心概念

概念描述作用
资源 (Resource)Sentinel 中最核心的概念。可以是任何您希望保护的代码块、服务、方法、接口等。用唯一名称标识。定义流量防护的目标。
规则 (Rule)为资源定义的具体保护措施,如流量阈值、降级策略等。定义如何保护资源(限流、降级、系统保护)。
Slot ChainSentinel 的核心处理链。当请求流经资源时,会依次经过统计、限流、熔断等各个 Slot(插槽)进行处理。Sentinel 工作的底层机制。

1-2、流量防护三大核心功能:

Sentinel 提供了三大保护功能,都基于对资源的实时统计

1. 🚦 流量控制 (Flow Control)

这是 Sentinel 最基本也是最重要的功能,目的是控制对资源的请求速度,确保其不超过系统的处理能力。

  • 指标: 通常基于 QPS(每秒查询数)并发线程数
  • 示例规则: 资源 getProductInfo 的 QPS 阈值为 200,当超过 200 QPS 时,后续请求将被拒绝(默认是 FailFast 策略)。

2. ⚡ 熔断降级 (Degrade)

依赖的资源或服务不稳定(响应慢或失败率高)时,Sentinel 会自动切断调用(熔断),让请求快速失败,而不是继续堆积,避免拖垮自身服务。

  • 策略:
    • 慢调用比例 (RT): 当资源的平均响应时间(RT)超过某个阈值,并且请求量也达到一定值时,触发熔断。
    • 异常比例: 当资源的异常请求比例达到阈值时,触发熔断。
    • 异常数: 在一个时间窗口内,异常请求总数达到阈值时,触发熔断。
  • 熔断器状态: 正常 -> 打开 (Open) -> 半开 (Half-Open) -> 正常。熔断打开后,在设定的恢复时间窗后进入半开状态尝试放行少量请求。

3. 🛡️ 系统保护 (System Protection)

整个系统的维度进行负载保护,而不是针对单个资源。它基于系统的整体负载指标(如 CPU 利用率、系统 Load、平均 RT 等)进行判断和限流。

  • 作用: 防止系统压力过大时,雪崩式地拒绝所有请求,保护核心业务,同时保证非核心业务的快速失败。

二、Sentinel 快速入门步骤(基于 Spring Cloud/SpringBoot)

步骤一:部署 Sentinel Dashboard (TC)

Sentinel 的规则和监控信息通常通过控制台(Dashboard)来配置和查看。

  • 下载: 从 Sentinel GitHub 或 Maven Central 下载最新的sentinel-dashboard.jar
  • 启动: 运行 Dashboard。默认端口是 8080
  • java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -jar sentinel-dashboard.jar
  • 访问: 浏览器访问 http://localhost:8080,默认账号/密码是 sentinel/sentinel

步骤二:集成到业务微服务

引入依赖: 在需要进行流量防护的微服务中引入 Sentinel 依赖(推荐使用 Spring Cloud Alibaba 提供的 starter)。

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

配置客户端:application.propertiesapplication.yml 中配置服务名和 Dashboard 地址。

# application.yml
spring:
  application:
    name: your-service-name
# 配置 Sentinel Dashboard 地址
cloud:
  sentinel:
    transport:
      dashboard: localhost:8080

定义资源 (Resource):

import com.alibaba.csp.sentinel.annotation.SentinelResource;
@Service
public class OrderService {
    // 使用 @SentinelResource 保护方法
    @SentinelResource(value = "createOrder", 
                      blockHandler = "handleBlock", // 违背限流/降级规则时调用的方法
                      fallback = "handleFallback") // 业务异常时调用的方法
    public String createOrder(String userId) {
        // 核心业务逻辑
        return "Order created successfully";
    }
    // 限流或降级时的处理逻辑(参数要匹配原方法)
    public String handleBlock(String userId, BlockException ex) {
        System.out.println("Blocked by Sentinel: " + ex.getMessage());
        return "System busy, please try later.";
    }
    // 业务异常时的处理逻辑(Throwable 参数)
    public String handleFallback(String userId, Throwable ex) {
        System.out.println("Service logic error: " + ex.getMessage());
        return "Internal error occurred.";
    }
}
  • 自动定义 (Automatic): Sentinel 会自动将 HTTP 接口、Feign 客户端调用、Dubbo 接口等识别为资源
  • 手动定义 (Manual): 使用 @SentinelResource注解来保护您代码中的关键业务逻辑。
  • 配置规则:
    • 启动您的微服务并调用几次被 @SentinelResource 保护的方法。(懒加载
    • 登录 Sentinel Dashboard,在左侧菜单找到您的服务。
    • 进入 簇点链路 找到您定义的资源(如 createOrder),然后点击右侧的 新增限流新增降级 规则。
  • 例如: 设置 createOrderQPS 阈值 为 10,流控模式快速失败 (Fail Fast)

企业级最佳实践

  • 持久化规则: Dashboard 配置的规则默认只存在内存中,重启后丢失。企业级应用必须将规则持久化到配置中心(如 Nacos、Apollo),以确保规则的动态性持久性
  • 区分降级和限流处理:
    • blockHandler:处理 Sentinel 规则 导致的异常(限流、降级、系统保护)。
    • fallback:处理 业务代码 执行时抛出的异常(如数据库连接失败、空指针等)。
  • 统一入口: 对外部提供的 API Gateway 接口是最重要的限流资源,应优先配置保护。

三、@SentinelResource一般是加在哪里?

@SentinelResource 是Sentinel的限流降级注解。

3-1、加在哪里

1. Service层方法(最常见)

@Service
public class OrderService {
    @SentinelResource(
        value = "createOrder",
        blockHandler = "handleCreateOrderBlock",
        fallback = "createOrderFallback"
    )
    public Order createOrder(Order order) {
        // 业务逻辑
        return orderMapper.insert(order);
    }
    // 处理限流(BlockException)
    public Order handleCreateOrderBlock(Order order, BlockException e) {
        log.warn("订单创建被限流了");
        return null;
    }
    // 处理熔断降级(业务异常)
    public Order createOrderFallback(Order order, Throwable e) {
        log.warn("订单创建失败,执行降级方案");
        return new Order();  // 返回默认值
    }
}

2. Controller层方法

@RestController
@RequestMapping("/api/orders")
public class OrderController {
    @Autowired
    private OrderService orderService;
    @PostMapping
    @SentinelResource(
        value = "createOrderApi",
        blockHandler = "handleBlock"
    )
    public ApiResponse<Order> createOrder(@RequestBody Order order) {
        Order result = orderService.createOrder(order);
        return ApiResponse.success(result);
    }
    public ApiResponse<Order> handleBlock(Order order, BlockException e) {
        return ApiResponse.fail("系统繁忙,请稍后再试");
    }
}

3. Feign客户端方法

@FeignClient(name = "stock-service", fallback = StockServiceFallback.class)
public interface StockServiceClient {
    @PostMapping("/api/stock/deduct")
    @SentinelResource(
        value = "deductStock",
        fallback = "deductStockFallback"
    )
    Stock deductStock(@RequestParam Long productId, @RequestParam Integer quantity);
    default Stock deductStockFallback(Long productId, Integer quantity) {
        log.warn("库存服务调用失败,执行降级");
        return new Stock();
    }
}

4. 异步方法

@Service
public class AsyncOrderService {
    @Async
    @SentinelResource(
        value = "asyncProcessOrder",
        blockHandler = "handleAsyncBlock"
    )
    public void processOrderAsync(Order order) {
        // 异步处理逻辑
        doSomeHeavyWork(order);
    }
    public void handleAsyncBlock(Order order, BlockException e) {
        log.warn("异步处理被限流");
    }
}

3-2、一般不加的地方

❌ 不加在Mapper层

// 错误示范
@Mapper
public interface OrderMapper {
    @SentinelResource("selectOrder")  // ❌ 不要加这儿
    Order selectById(Long id);
}
// 原因:
// 1. Mapper直接操作数据库,没有业务逻辑
// 2. 限流应该在业务层面
// 3. 多个Service可能调用同一个Mapper

❌ 不加在private私有方法

@Service
public class OrderService {
    @SentinelResource("privateMethod")  // ❌ 不要加
    private void privateMethod() {
        // ...
    }
    // 原因:Sentinel是通过代理实现的,私有方法代理不了
}

❌ 不加在构造方法

@Service
public class OrderService {
    @SentinelResource("constructor")  // ❌ 不要加
    public OrderService() {
        // ...
    }
}

❌ 不加在static方法

@Service
public class OrderService {
    @SentinelResource("staticMethod")  // ❌ 不要加
    public static void staticMethod() {
        // ...
    }
    // 原因:static方法不能被代理
}

3-3、最佳实践

推荐做法:Service + Controller双层

// ===== Controller层 =====
@RestController
@RequestMapping("/api/orders")
public class OrderController {
    @SentinelResource(
        value = "createOrderApi",  // API级别的限流
        blockHandler = "apiBlockHandler"
    )
    @PostMapping
    public ApiResponse<Order> createOrder(@RequestBody Order order) {
        return ApiResponse.success(orderService.createOrder(order));
    }
    public ApiResponse<Order> apiBlockHandler(Order order, BlockException e) {
        return ApiResponse.fail("API请求过于频繁");
    }
}
// ===== Service层 =====
@Service
public class OrderService {
    @SentinelResource(
        value = "createOrderService",  // 业务级别的限流
        blockHandler = "serviceBlockHandler",
        fallback = "createOrderFallback"
    )
    public Order createOrder(Order order) {
        // 实际业务逻辑
        return orderMapper.insert(order);
    }
    public Order serviceBlockHandler(Order order, BlockException e) {
        return null;  // 限流处理
    }
    public Order createOrderFallback(Order order, Throwable e) {
        return new Order();  // 降级处理
    }
}

为什么双层?

用户请求
    ↓
Controller层(@SentinelResource)
    ├─ 控制HTTP请求的流量
    ├─ 返回友好的错误信息
    └─ 保护系统入口
    ↓
Service层(@SentinelResource)
    ├─ 控制业务操作的流量
    ├─ 保护核心业务逻辑
    └─ 其他Service也可能调用

3-4、@SentinelResource 注解参数说明

@SentinelResource(
    value = "createOrder",              // 资源名,必需
    blockHandler = "handleBlock",       // 限流/降级时的处理方法
    blockHandlerClass = BlockHandlers.class,  // 指定外部类
    fallback = "fallbackMethod",        // 业务异常时的降级方法
    fallbackClass = FallbackMethods.class,    // 指定外部类
    exceptionsToIgnore = {IOException.class}  // 忽略的异常
)
public Order createOrder(Order order) {
    // ...
}

3-5、常见场景总结

场景位置用途
保护HTTP接口Controller限制请求频率
保护业务方法Service限制业务操作
远程调用降级Feign客户端调用失败降级
异步任务保护@Async方法限制异步线程
定时任务保护@Scheduled方法限制定时任务

简单总结:加在Service和Controller的public业务方法上,不要加在Mapper、私有方法、static方法。

到此这篇关于Spring Cloud Sentinel入门讲解的文章就介绍到这了,更多相关Spring Cloud Sentinel入门内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中不定参数用法小结

    Java中不定参数用法小结

    在Java中,不定参数是指方法的参数数量可以变化的情况,本文主要介绍了Java中不定参数用法,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • SpringBoot如何使用MyBatisPlus逆向工程自动生成代码

    SpringBoot如何使用MyBatisPlus逆向工程自动生成代码

    本文介绍如何使用SpringBoot、MyBatis-Plus进行逆向工程自动生成代码,并结合Swagger3.0实现API文档的自动生成和访问,通过详细步骤和配置,确保Swagger与SpringBoot版本兼容,并通过配置文件和测试类实现代码生成和Swagger文档的访问
    2024-12-12
  • 浅谈SpringBoot如何封装统一响应体

    浅谈SpringBoot如何封装统一响应体

    今天带各位小伙伴学习SpringBoot如何封装统一响应体,文中有非常详细的介绍及代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-05-05
  • SpringBoot高并发下控制限流的几种实现方法

    SpringBoot高并发下控制限流的几种实现方法

    随着业务的发展,高并发成为很多系统不得不面对的问题,限流作为一种常用的技术手段,可以帮助我们有效地控制请求的流量,避免系统因过载而崩溃,本文将介绍在Spring Boot应用中实现限流的几种方法,需要的朋友可以参考下
    2024-06-06
  • Java线程安全的计数器简单实现代码示例

    Java线程安全的计数器简单实现代码示例

    这篇文章主要介绍了Java线程安全的计数器简单实现代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • Java应该在哪里判断List是否为空

    Java应该在哪里判断List是否为空

    在Java中,我们常用List来存储数据,但是我们怎么判断它是否成功带来了我们需要的数据呢?下面这篇文章主要给大家介绍了关于Java应该在哪里判断List是否为空的相关资料,需要的朋友可以参考下
    2022-02-02
  • Java多线程中synchronized的工作原理

    Java多线程中synchronized的工作原理

    这篇文章主要介绍了Java多线程中synchronized的工作原理,本期讲解 synchronized 工作的原理以及常见的锁优化机制,相信大家在看完这篇博文后对 synchronized 工作流程有一定的理解,需要的朋友可以参考下
    2023-07-07
  • JavaFX实现简易时钟效果(二)

    JavaFX实现简易时钟效果(二)

    这篇文章主要为大家详细介绍了JavaFX实现简易时钟效果的第二篇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • Java中CyclicBarrier的用法分析

    Java中CyclicBarrier的用法分析

    CyclicBarrier和CountDownLatch一样,都是关于线程的计数器。用法略有不同,测试代码如下:
    2013-03-03
  • Java实现公用实体类转Tree结构

    Java实现公用实体类转Tree结构

    这篇文章主要为大家介绍了一个Java工具类,可以实现Java公用实体类转Tree结构,文中的示例代码简洁易懂,感兴趣的小伙伴可以参考一下
    2024-10-10

最新评论