java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring Cloud Sentinel入门

Spring Cloud Sentinel快速入门步骤

作者:ruleslol

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

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

一、Sentinel 核心概念与目标

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

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

1-1. 核心概念

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

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

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

1. 🚦 流量控制 (Flow Control)

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

2. ⚡ 熔断降级 (Degrade)

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

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

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

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

步骤一:部署 Sentinel Dashboard (TC)

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

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

引入依赖: 在需要进行流量防护的微服务中引入 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.";
    }
}

企业级最佳实践

三、@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入门内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文