微服务服务保护:Sentinel 从入门到流控规则实战

一、高并发下的服务雪崩问题

在微服务架构中,服务间通过网络调用,若单个服务故障且大量请求涌入,会导致任务堆积,最终引发服务雪崩(调用链路中某个服务故障,导致整条链路不可用)。

1.1 模拟高并发场景(基础工程搭建)

1.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 复制代码
package com.hg.service;

import com.hg.pojo.User;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
	@Override
	public User getUserById(Integer id) {
		// 模拟网络延时2秒
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return new User(id,"王粪堆-provider",18);
	}
}
1.1.2 Feign 接口(sentinel_feign)
java 复制代码
package com.hg.feign;

import com.hg.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient("sentinel-provider")
public interface UserFeign {
    @RequestMapping(value = "/provider/getUserById/{id}")
    public User getUserById(@PathVariable Integer id);
}
1.1.3 服务消费者(sentinel_consumer)

pom.xml 核心依赖:

XML 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </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>
</dependencies>

application.yml(限制 tomcat 线程数):

XML 复制代码
server:
  tomcat:
    max-threads: 10 # 降低tomcat最大并发,模拟资源不足
feign:
  client:
    config:
      default:
        connectionTimeout: 5000 
        readTimeout: 5000    

测试接口

java 复制代码
@RequestMapping(value = "/hello")
public String hello() {
    return "Hello Sentienl!!!";
}
1.1.4 压测验证雪崩雏形
  1. 下载 JMeter,配置线程组(高并发),调用http://127.0.0.1:8080/consumer/getUserById/1
  2. 同时访问http://127.0.0.1:8080/consumer/hello,发现 hello 接口阻塞等待 ------ 服务雪崩雏形出现。

1.2 Sentinel 核心概念与入门

1.2.1 Sentinel 是什么?

Sentinel(分布式系统的流量防卫兵)是阿里开源的服务保护框架,以流量 为切入点,通过流量控制、熔断降级等维度保障服务稳定性。

1.2.2 核心概念
  • 资源:Sentinel 要保护的对象(如接口、方法);
  • 规则:保护资源的策略(流量控制、熔断降级等)。
1.2.3 Sentinel 入门实现(两种方式)
方式 1:抛异常方式(原生 API)

添加依赖

XML 复制代码
<dependency>
	<groupId>com.alibaba.csp</groupId>
	<artifactId>sentinel-core</artifactId>
</dependency>

接口改造 + 限流规则配置

java 复制代码
@RequestMapping(value = "/hello")
public String hello() {
    Entry entry = null;
    try {
        // 定义资源,Sentinel检查规则
        entry = SphU.entry("/consumer/hello");
        return "Hello Sentienl!!!";
    } catch (BlockException e) {
        // 限流兜底逻辑
        e.printStackTrace();
        return "接口被限流了, exception: " + e;
    }finally {
        if (entry != null) {
            entry.exit(); // 必须与entry成对出现
        }
    }
}

// 初始化限流规则
@PostConstruct
public void initFlowQpsRule() {
    List<FlowRule> rules = new ArrayList<FlowRule>();
    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); // 加载规则
}
方式 2:注解方式(低侵入)

添加依赖

XML 复制代码
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
</dependency>

开启注解支持 + 接口改造

java 复制代码
// 启动类/配置类中注册Bean
@Bean
public SentinelResourceAspect sentinelResourceAspect(){
    return new SentinelResourceAspect();
}

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

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

// 规则配置(同方式1,仅修改资源名)
@PostConstruct
public void initFlowQpsRule() {
    List<FlowRule> rules = new ArrayList<FlowRule>();
    FlowRule rule1 = new FlowRule();
    rule1.setResource("/consumer/hello2");
    rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule1.setCount(2);
    rules.add(rule1);
    FlowRuleManager.loadRules(rules);
}
1.2.4 Sentinel 控制台接入
  1. 下载启动控制台 :下载地址:https://github.com/alibaba/Sentinel/releases启动命令:java -jar sentinel-dashboard-1.8.1.jar访问地址:http://localhost:8080(默认账号 / 密码:sentinel/sentinel)

  2. 客户端接入控制台

    1)添加依赖:

XML 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2)配置 yml:

XML 复制代码
spring:
  cloud:
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080 # 控制台地址

3)访问任意接口(触发 Sentinel 懒加载),即可在控制台看到监控数据。

二、Sentinel 流控规则全解析

流控规则核心参数说明:

参数 说明
资源名 唯一名称,默认请求路径
针对来源 限流调用方(微服务名),默认 default(不区分来源)
阈值类型 QPS(每秒访问次数)/ 线程数(每秒访问线程数)
流控模式 直接(限流当前资源)/ 关联(关联资源阈值触发限流)/ 链路(指定接口触发)
流控效果 快速失败 / Warm Up / 排队等待

2.1 阈值类型

2.1.1 QPS 限流
  • 逻辑:当接口 QPS 达到阈值时,直接限流;
  • 实战步骤
    1. 控制台新增流控规则(资源名:/consumer/getUserById/{id},阈值类型 QPS,阈值 2);
    2. JMeter 高并发调用http://127.0.0.1/consumer/getUserById/1,触发限流。
2.1.2 线程数限流
  • 逻辑:当访问接口的线程数达到阈值时,触发限流(适合慢接口);
  • 实战步骤
    1. 控制台新增流控规则(阈值类型:线程数,阈值 5);
    2. JMeter 模拟多线程调用,线程数超过 5 时触发限流。

2.2 流控模式

2.2.1 直接模式

默认模式,直接对当前资源的 QPS / 线程数限流(上文案例均为直接模式)。

2.2.2 关联模式
  • 逻辑:关联资源达到阈值时,限流当前资源(适合 "应用让步" 场景,如支付接口阈值触发,限流订单接口);
  • 实战步骤
    • 新增测试接口:
java 复制代码
@RequestMapping(value="/test")
public String test(){
    return "test";
}
    • 控制台配置流控规则(资源名:/consumer/getUserById/{id},流控模式:关联,关联资源:/consumer/test,阈值 2);
    • JMeter 高并发调用/consumer/test,触发/consumer/getUserById/{id}限流。
2.2.3 链路模式
  • 逻辑:指定上级接口触发限流(粒度比 "针对来源" 更细);
  • 说明:需配置链路入口,实战中较少用(略)。

2.3 流控效果

2.3.1 快速失败

默认效果,触发限流时直接返回异常(Sentinel 默认提示)。

2.3.2 Warm Up(预热模式)
  • 逻辑 :QPS 阈值从阈值/3开始,经 "预热时长" 逐步升至设定阈值(适合流量突增场景);
  • 实战步骤
    1. 控制台配置(流控效果:Warm Up,预热时长 5 秒,QPS 阈值 6);
    2. 前 5 秒访问接口,QPS 超过 2(6/3)即限流;5 秒后阈值升至 6,可正常访问。
2.3.3 排队等待
  • 逻辑:请求匀速通过,超出阈值的请求排队等待(超时丢弃),保证服务负载均匀;
  • 实战步骤
    1. 控制台配置(流控效果:排队等待,QPS 阈值 1,超时时间 10ms);
    2. 接口添加时间打印:
java 复制代码
@RequestMapping(value = "/getUserById/{id}")
public User getUserById(@PathVariable Integer id) {
    System.out.println("排队等待效果:"+new Date());
    return userFeign.getUserById(id);
}

高并发调用接口,控制台打印日志间隔约 1 秒(匀速处理),超时请求被丢弃。

相关推荐
智能化咨询2 小时前
(199页PPT)DG企业架构企业IT战略规划架构设计方案(附下载方式)
大数据·架构
张忠琳2 小时前
【openclaw】OpenClaw Cron 模块超深度架构分析之二服务层与定时器引擎
ai·架构·openclaw
2501_933329552 小时前
品牌公关实战:Infoseek数字公关AI中台技术架构与舆情处置全流程解析
人工智能·自然语言处理·架构·数据库开发
数字供应链安全产品选型2 小时前
2026 AI智能体安全治理深度报告:从“决策黑盒”到“全链路可溯”,悬镜灵境AIDR的技术架构与实践路径
人工智能·安全·架构
Giggle12182 小时前
从零解构一套校园外卖系统:架构设计、技术选型与核心难点剖析
java·运维·微服务
youyudehexie2 小时前
云原生与边缘计算融合驱动下一代互联网架构创新探索实践
云原生·架构·边缘计算
zhoupenghui1682 小时前
搭建VictoriaLogs集中式日志管理系统来解决 微服务 “请求跨越多个服务”时报错的全链路追踪与快速排查 问题
微服务·云原生·架构·链路追踪·victorialogs·logs explorer
小旭95273 小时前
微服务服务容错保护:Sentinel 从入门到实战
微服务·架构·sentinel
LONGZETECH3 小时前
破解汽车实训难题!龙泽科技仿真软件,助力院校教学与大赛备赛
人工智能·科技·架构·汽车·汽车仿真教学软件