在微服务架构中,服务的稳定性至关重要。随着服务数量增多和调用关系复杂化,服务熔断、限流、隔离等保护机制成为保障系统稳定性的关键。Sentinel 作为阿里巴巴开源的流量控制组件,为我们提供了一站式的服务保护解决方案。本文将带你快速入门 Sentinel,实现请求限流线程隔离服务熔断功能。

什么是 Sentinel?

Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助开发者保障微服务的稳定性。

核心特性:

  • 丰富的流量控制策略(基于QPS、线程数等)
  • 熔断降级能力(基于响应时间、异常比例等)
  • 系统自适应保护
  • 实时监控和控制台
  • 易用的扩展点

环境准备

技术栈

  • JDK 1.8+
  • Spring Boot 2.7.x(本文以Spring Boot为例)
  • Maven 3.6+

引入依赖

pom.xml 中添加以下依赖:

<!-- Sentinel 核心依赖 -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.8.6</version>
</dependency>

<!-- Spring Boot 集成 Sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2021.0.5.0</version>
</dependency>

<!-- Sentinel 控制台通信依赖 -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>1.8.6</version>
</dependency>

下载并启动 Sentinel 控制台

  1. Sentinel Releases 下载控制台 jar 包(例如:sentinel-dashboard-1.8.6.jar)
  2. 启动控制台:

    java -jar sentinel-dashboard-1.8.6.jar --server.port=8080
  3. 访问 http://localhost:8080,默认用户名/密码:sentinel/sentinel

配置应用连接控制台

application.yml 中添加配置:

spring:
  application:
    name: sentinel-demo
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080  # 控制台地址
        port: 8719  # 本地客户端端口,默认8719,如被占用会自动加1

server:
  port: 8081

核心功能实现

1. 请求限流

限流是保护服务的第一道防线,防止流量突增导致服务崩溃。

基于注解的限流实现

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.RestController;

@RestController
public class LimitController {

    /**
     * 基础限流示例
     * value: 资源名称,必填
     * blockHandler: 限流/降级后的处理方法
     */
    @GetMapping("/limit")
    @SentinelResource(value = "limitResource", blockHandler = "handleLimit")
    public String limit() {
        return "正常访问:" + System.currentTimeMillis();
    }

    // 限流处理方法,参数和返回值需与原方法一致,并额外添加BlockException参数
    public String handleLimit(BlockException e) {
        return "请求过于频繁,请稍后再试!";
    }
}

在控制台配置限流规则

  1. 启动应用后,访问一次 /limit 接口(Sentinel 采用懒加载机制,首次访问后才会在控制台显示)
  2. 进入控制台 -> 簇点链路 -> 找到 limitResource 资源
  3. 点击 "流控",配置规则:

    • 阈值类型:QPS
    • 单机阈值:5(每秒最多5次请求)
    • 其他保持默认

现在快速刷新 /limit 接口,超过5次/秒就会触发限流。

2. 线程隔离

线程隔离用于控制某个服务调用的资源消耗,避免单个服务故障影响整个应用。Sentinel 支持两种隔离方式:线程池隔离和信号量隔离。

线程池隔离实现

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.RestController;

@RestController
public class IsolationController {

    /**
     * 线程池隔离示例
     */
    @GetMapping("/isolation")
    @SentinelResource(value = "isolationResource", 
                     blockHandler = "handleIsolation",
                     fallback = "fallbackIsolation")
    public String isolation() throws InterruptedException {
        // 模拟耗时操作
        Thread.sleep(100);
        return "隔离服务正常响应";
    }

    // 限流/降级处理
    public String handleIsolation(BlockException e) {
        return "服务繁忙,请稍后再试";
    }

    // 业务异常处理
    public String fallbackIsolation(Throwable e) {
        return "服务处理异常: " + e.getMessage();
    }
}

配置线程隔离规则

  1. 控制台 -> 簇点链路 -> isolationResource -> 点击 "流控"
  2. 选择 "线程数" 作为阈值类型
  3. 配置单机阈值(例如:3,表示最多同时处理3个请求)

当并发请求超过3个时,多余的请求会被阻塞并执行 handleIsolation 方法。

3. 服务熔断

当服务调用出现异常(如超时、错误率高)时,熔断机制会暂时停止调用该服务,避免级联故障,待服务恢复后再逐步恢复调用。

熔断示例实现

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CircuitBreakerController {

    private int errorCount = 0;

    /**
     * 熔断降级示例
     */
    @GetMapping("/breaker")
    @SentinelResource(value = "breakerResource", 
                     fallback = "breakerFallback",
                     blockHandler = "breakerBlockHandler")
    public String breaker() {
        errorCount++;
        // 模拟50%的错误率
        if (errorCount % 2 == 0) {
            throw new RuntimeException("服务内部错误");
        }
        return "服务正常响应";
    }

    // 熔断后的降级处理
    public String breakerFallback(Throwable e) {
        return "服务已熔断,暂时无法提供服务: " + e.getMessage();
    }

    // 限流处理
    public String breakerBlockHandler(BlockException e) {
        return "请求被限流";
    }
}

配置熔断规则

  1. 控制台 -> 簇点链路 -> breakerResource -> 点击 "降级"
  2. 配置熔断规则:

    • 降级策略:异常比例
    • 比例阈值:0.5(错误率超过50%)
    • 熔断时长:10(熔断10秒)
    • 最小请求数:5(至少5个请求才开始计算错误率)

连续访问 /breaker 接口,当错误率超过50%时,服务会进入熔断状态,10秒内所有请求都会直接返回降级结果。

规则持久化

默认情况下,Sentinel 规则存储在内存中,应用重启后会丢失。生产环境需要配置规则持久化。

以 Nacos 为例配置规则持久化:

  1. 添加依赖:

    <dependency>
     <groupId>com.alibaba.csp</groupId>
     <artifactId>sentinel-datasource-nacos</artifactId>
     <version>1.8.6</version>
    </dependency>
  2. 配置 Nacos 数据源:

    spring:
      cloud:
     sentinel:
       datasource:
         ds1:
           nacos:
             server-addr: localhost:8848
             dataId: sentinel-rules
             groupId: DEFAULT_GROUP
             rule-type: flow  # 支持flow, degrade, param-flow, system, authority

总结

本文介绍了 Sentinel 的核心功能及基本使用方法:

  1. 请求限流:通过控制QPS或线程数保护服务不被流量冲垮
  2. 线程隔离:限制服务调用的资源占用,避免级联故障
  3. 服务熔断:当服务异常时自动熔断,保护系统稳定

Sentinel 还提供了更高级的特性,如参数限流、系统自适应保护、网关限流等,可根据实际需求深入学习。

通过合理配置这些保护机制,能有效提高微服务架构的稳定性和可靠性,从容应对各种流量场景。

参考资料


本文作者:
文章标签:Java指南微服务Spring Cloud服务治理
文章标题:Java 基于 Sentinel 的服务保护入门指南:请求限流、线程隔离和服务熔断
本文地址:https://www.ducky.vip/archives/sentinel.html
版权说明:若无注明,本文皆 iDuckie's Blog 原创,转载请保留文章出处。
最后修改:2024 年 04 月 29 日
如果觉得我的文章对你有用,请随意赞赏