SpringCloud Alibaba Sentinel 从入门到精通

前言

在微服务架构中,服务间的依赖关系复杂,一个服务的故障可能引发连锁反应,导致整个系统雪崩。Sentinel 作为阿里巴巴开源的流量控制框架,能从流量控制、熔断降级等维度保护服务稳定性。本文将从实战角度,完整讲解 Sentinel 的核心概念、使用方式及各类规则配置。

一、Sentinel 核心概念

1.1 什么是 Sentinel

Sentinel(分布式系统的流量防卫兵)以流量为切入点,提供流量控制熔断降级系统负载保护等能力,保障微服务高可用。

1.2 核心概念

  • 资源:Sentinel 要保护的对象,可是一个接口、方法、服务等。
  • 规则:定义保护资源的策略,包括流量控制、熔断降级、热点参数、系统规则、授权规则等。
  • 核心功能
    • 流量控制:限制接口 QPS / 线程数,避免服务被压垮。
    • 熔断降级:当下游服务异常时,暂时切断调用,防止级联故障。

二、环境准备

2.1 搭建基础微服务

2.1.1 服务提供者(sentinel-provider)

application.yml

复制代码
server:
  port: 9090
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.209.129:8848
  application:
    name: sentinel-provider

核心服务类

java 复制代码
@Service
public class UserServiceImpl implements UserService {
    @Override
    public User getUserById(Integer id) {
        // 模拟网络延时
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new User(id,"王粪堆-provider",18);
    }
}
2.1.2 Feign 接口(sentinel_feign)
java 复制代码
@FeignClient("sentinel-provider")
public interface UserFeign {
    @RequestMapping(value = "/provider/getUserById/{id}")
    public User getUserById(@PathVariable Integer id);
}
2.1.3 服务消费者(sentinel_consumer)

pom.xml

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud_parent</artifactId>
        <groupId>com.hg</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>sentinel_consumer</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.hg</groupId>
            <artifactId>springcloud_common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--feign接口-->
        <dependency>
            <groupId>com.hg</groupId>
            <artifactId>sentinel_feign</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--Sentinel核心依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
    </dependencies>
</project>

application.yml

复制代码
server:
  port: 8080
  tomcat:
    max-threads: 10 # 降低tomcat并发,便于测试雪崩
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.209.129:8848
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080 # Sentinel控制台地址
feign:
  client:
    config:
      default:
        connectionTimeout: 5000
        readTimeout: 5000
  sentinel:
    enabled: true # 开启Feign整合Sentinel

三、Sentinel 快速入门

3.1 方式 1:硬编码(抛异常方式)

java 复制代码
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
    @RequestMapping(value = "/hello")
    public String hello() {
        Entry entry = null;
        try {
            // 定义资源
            entry = SphU.entry("/consumer/hello");
            return "Hello Sentinel!!!";
        } catch (BlockException e) {
            // 限流兜底逻辑
            return "接口被限流了, exception: " + e;
        }finally {
            if (entry != null) {
                entry.exit();
            }
        }
    }

    // 初始化限流规则
    @PostConstruct
    public void initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource("/consumer/hello"); // 资源名
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS); // 按QPS限流
        rule1.setCount(2); // QPS阈值2
        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
    }
}

3.2 方式 2:注解方式(推荐)

java 复制代码
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
    // 开启Sentinel注解支持
    @Bean
    public SentinelResourceAspect sentinelResourceAspect(){
        return new SentinelResourceAspect();
    }

    @RequestMapping(value = "/hello2")
    @SentinelResource(value="/consumer/hello2",blockHandler = "blockHandlerMethod")
    public String hello2() {
        return "Hello Sentinel2!!!";
    }

    // 限流兜底方法
    public String blockHandlerMethod(BlockException e){
        return "接口被限流了, exception: " + e;
    }

    @PostConstruct
    public void initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource("/consumer/hello2");
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule1.setCount(2);
        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
    }
}

3.3 Sentinel 控制台使用

3.3.1 启动控制台

bash

复制代码
# 下载地址:https://github.com/alibaba/Sentinel/releases
java -jar sentinel-dashboard-1.8.1.jar

访问 http://localhost:8080,默认账号 / 密码:sentinel/sentinel。

3.3.2 接入控制台

消费者配置文件中添加:

yaml:

复制代码
spring:
  cloud:
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080

访问任意接口(如 http://127.0.0.1:8080/consumer/hello3),控制台即可识别服务。

四、Sentinel 核心规则配置

4.1 流量控制规则

流量控制是 Sentinel 最核心的功能,通过限制 QPS / 线程数,防止服务被压垮。

4.1.1 核心配置项说明
配置项 说明
资源名 唯一标识,默认请求路径
针对来源 限制调用方(默认 default,不区分来源)
阈值类型 QPS(每秒请求数)/ 线程数
流控模式 直接(限流当前接口)/ 关联(关联接口阈值触发限流)/ 链路(指定入口限流)
流控效果 快速失败 / Warm Up(预热)/ 排队等待
4.1.2 典型场景配置
(1)QPS 限流
  • 规则配置:资源名 /consumer/getUserById/{id},阈值类型 QPS,单机阈值 2;
  • 效果:接口 QPS 超过 2 时,直接触发限流。
(2)Warm Up(预热限流)
  • 适用场景:流量突增(如秒杀),避免瞬间打满服务;
  • 规则配置:阈值类型 QPS,单机阈值 6,预热时长 5 秒;
  • 效果:QPS 从 2(6/3)开始,5 秒后升至 6,平滑提升流量处理能力。
(3)排队等待
  • 适用场景:需要匀速处理请求(如削峰填谷);
  • 规则配置:阈值类型 QPS,单机阈值 1,排队超时时间 10ms;
  • 效果:请求匀速通过,超时未处理的请求直接丢弃。

4.2 热点参数限流

对接口参数做精细化限流,支持参数例外项(如特定 ID 放宽阈值)。

java 复制代码
@RequestMapping(value = "/getUserById/{id}")
@SentinelResource(value = "getUserById", blockHandler = "blockHandlerMethod")
public User getUserById(@PathVariable Integer id) {
    return userFeign.getUserById(id);
}

// 热点参数限流兜底方法
public User blockHandlerMethod(Integer id, BlockException e) {
    return new User(id, "热点参数限流触发", 0);
}
  • 规则配置:资源名 getUserById,参数索引 0(第一个参数),单机阈值 2;
  • 例外项配置:参数值 2,阈值 3(ID=2 时 QPS 阈值提升至 3)。

4.3 熔断降级规则

当接口响应慢 / 异常比例高时,暂时切断调用,避免级联故障。

4.3.1 三种熔断策略
策略 触发条件
慢调用比例 慢调用(RT 超过阈值)占比超过设定值,且请求数≥最小请求数
异常比例 异常请求占比超过设定值,且请求数≥最小请求数
异常数 异常请求数超过设定值,且请求数≥最小请求数
4.3.2 配置示例(慢调用比例)
  • 规则配置:资源名 /consumer/getUserById/{id},最大 RT 200ms,比例阈值 0.5,熔断时长 5s,最小请求数 5;
  • 效果:5 个请求中若 50% 以上 RT 超过 200ms,触发熔断,5 秒内拒绝所有请求。

4.4 授权规则

基于请求来源做黑白名单控制,适合接口访问权限管控。

4.4.1 实现来源解析
java 复制代码
@Component
public class RequestOriginParserDefinition implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest request) {
        // 从请求参数获取来源标识(可替换为请求头、Session等)
        return request.getParameter("origin");
    }
}
4.4.2 规则配置
  • 黑名单:资源名 /consumer/getUserById/{id},黑名单值 app1
  • 效果:来源为 app1 的请求直接被拒绝。

4.5 系统规则

针对整个应用的全局规则(粒度粗,慎用),支持:

  • LOAD(Linux 系统负载);
  • RT(所有请求平均响应时间);
  • 线程数(所有请求总线程数);
  • 入口 QPS(所有接口总 QPS);
  • CPU 使用率。

五、Sentinel 高级特性

5.1 自定义兜底逻辑(blockHandler)

5.1.1 同级别兜底(当前类)
java 复制代码
@SentinelResource(value = "getUserById", blockHandler = "blockHandlerMethod")
public User getUserById(@PathVariable Integer id) {
    return userFeign.getUserById(id);
}

// 兜底方法(参数与原方法一致,最后加BlockException)
public User blockHandlerMethod(Integer id, BlockException e) {
    return new User(0, "接口被流控/熔断:"+e, 0);
}
5.1.2 外置兜底类(解耦)
java 复制代码
// 外置兜底类(方法必须static)
public class BlockHandlerClass {
    public static User blockHandlerMethod(Integer id, BlockException e) {
        return new User(0, "外置兜底:"+e, 0);
    }
}

// 使用外置兜底类
@SentinelResource(value = "getUserById",
        blockHandler = "blockHandlerMethod",
        blockHandlerClass = BlockHandlerClass.class)
public User getUserById(@PathVariable Integer id) {
    return userFeign.getUserById(id);
}

5.2 全局异常处理

统一处理 Sentinel 各类异常,返回标准化响应。

java 复制代码
@Component
public class GlobalBlockExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        Result data = null;
        if (e instanceof FlowException) {
            data = new Result(-1, "限流异常");
        } else if (e instanceof DegradeException) {
            data = new Result(-2, "降级异常");
        } else if (e instanceof ParamFlowException) {
            data = new Result(-3, "参数限流异常");
        } else if (e instanceof AuthorityException) {
            data = new Result(-4, "授权异常");
        } else if (e instanceof SystemBlockException) {
            data = new Result(-5, "系统负载异常");
        }
        response.getWriter().write(JSON.toJSONString(data));
    }
}

// 统一返回体
class Result {
    private int status;
    private String msg;
    private Object data;
    // 省略getter/setter/构造器
}

5.3 Sentinel 整合 Feign

实现 Feign 远程调用的熔断降级,避免下游服务异常影响上游。

5.3.1 实现 FallbackFactory
java 复制代码
@Component
public class UserFeignFallback implements FallbackFactory<UserFeign> {
    @Override
    public UserFeign create(Throwable t) {
        return new UserFeign() {
            @Override
            public User getUserById(Integer id) {
                return new User(id, "Feign调用失败:"+t, 0);
            }
        };
    }
}
5.3.2 配置 Feign 接口
java 复制代码
@FeignClient(value = "sentinel-provider", fallbackFactory = UserFeignFallback.class)
public interface UserFeign {
    @RequestMapping(value = "/provider/getUserById/{id}")
    User getUserById(@PathVariable Integer id);
}

六、总结

Sentinel 凭借轻量、易用、灵活的特性,成为 SpringCloud 微服务架构中服务保护的首选方案。核心要点总结:

  1. 资源定义:通过硬编码 / 注解 / 自动适配(SpringMVC/Feign)定义受保护资源;
  2. 规则配置:控制台 / 代码配置流量控制、熔断降级等规则,按需选择粒度;
  3. 兜底逻辑:通过 blockHandler / 全局异常 / FallbackFactory 处理限流 / 熔断场景;
  4. 核心价值:从流量入口到服务调用全链路保护,防止雪崩效应,保障微服务高可用。

建议结合 JMeter 压测工具验证各类规则效果,加深对 Sentinel 流量控制、熔断降级的理解,根据业务场景灵活配置规则,平衡系统稳定性和可用性。

相关推荐
JAVA学习通2 小时前
本地知识库接入大模型时的权限隔离与安全设计
java·人工智能·安全·spring
zhenxin012211 小时前
Spring Boot 3.x 系列【3】Spring Initializr快速创建Spring Boot项目
spring boot·后端·spring
oyzz12012 小时前
Spring EL 表达式的简单介绍和使用
java·后端·spring
后置的猿猴13 小时前
Spring 循环依赖
java·后端·spring
热爱Java,热爱生活14 小时前
浅谈Spring三级缓存
java·spring·缓存
shark222222216 小时前
Spring 的三种注入方式?
java·数据库·spring
hERS EOUS16 小时前
Spring Boot + Spring AI快速体验
人工智能·spring boot·spring
JAVA学习通17 小时前
LangChain4j 与 Spring AI 的技术选型深度对比:2026 年 Java AI 工程化实践指南
java·人工智能·spring
yaodong51818 小时前
Spring 中使用Mybatis,超详细
spring·tomcat·mybatis