当前位置: 首页 > news >正文

Spring Cloud Alibaba快速入门-Sentinel流量控制(FlowRule)

文章目录

  • 什么是流量控制(Flow Control)?
  • 新增流控规则
  • 流控模式
    • 直接策略(默认模式)
    • 链路策略
      • 触发逻辑
      • 场景
      • 特点
      • 示例
    • 关联策略
      • 触发逻辑
      • 场景
      • 特点
      • 示例
  • 流控效果
    • 快速失败
      • 核心思想
      • 适用场景
      • 特点
      • 示例
    • Warm Up(预热 / 冷启动)
      • 核心思想
      • 适用场景
      • 特点
      • 示例
    • 排队等待(Rate Limiting / Queueing)
      • 核心思想
      • 适用场景
      • 示例


在这里插入图片描述

什么是流量控制(Flow Control)?

核心思想:流量控制是 Sentinel 的“刹车系统”。它的原理是监控应用流量的 QPS(每秒查询率)或并发线程数等指标,当达到指定的阈值时,就采取预定的控制行为(如直接拒绝、排队等待等),以保证系统不会被突发流量冲垮,从而保障服务的高可用性。

简单来说,其目的就是 “避免让系统处理能力之外的需求涌入系统”。
在这里插入图片描述

新增流控规则

进入Sentinel页面,点击
在这里插入图片描述

在这里插入图片描述

  • 资源名:需要控制的资源名称
  • 针对来源:一般为default,表示无论从任何地方来的请求
  • 阈值类型:
    • QPS:统计每秒请求数,一般设置QPS
    • 并发线程数:统计并发线程数,统计线程池
  • 单机阈值:每秒数

在这里插入图片描述单机均摊:当均摊阈值为1时,集群中每一个机器每秒最多执行一次
总体阈值:当均摊阈值为1时,整个集群每秒最多执行一次

流控模式

在 Sentinel的流控模式中,直接、关联、链路是三种核心的流控模式,它们的核心区别在于触发流量控制的条件和场景不同
在这里插入图片描述

  • 调用关系包括调用方、被调用方;
  • 一个方法又可能会调用其它方法,形成一个调用链路的层次关系;
  • 有了调用链路的统计信息,我们可以衍生出多种流量控制手段。

在这里插入图片描述

直接策略(默认模式)

  • 触发逻辑:当当前资源自身的流量达到阈值时,直接对当前资源的请求进行限流。
  • 场景:最常用的模式,用于保护单个资源不被过度访问。
  • 特点:
    • 只关注当前资源的流量,与其他资源无关;
    • 配置简单,适用于绝大多数基础限流场景。

链路策略

触发逻辑

当从指定入口资源过来的请求访问当前资源时,若流量达到阈值,对该链路的请求进行限流(其他入口的请求不受影响)。(即:只限制 “特定调用链” 上的流量,允许其他链路正常访问当前资源)

场景

  • 用于精细化控制 “同一资源在不同调用链路下的流量”,避免某一条链路的异常流量影响其他链路。如:
    • 同一个Service方法被多个Controller调用。例如,UserService.getUserById() 方法既被 AdminController 调用,也被 AppController 调用。
    • 希望只限制来自 AdminController 这个调用链路的流量,而不影响 AppController 的正常用户访问。

特点

  • 限流范围限定在 “特定入口→当前资源” 的调用链路上;
  • 需通过如@SentinelResource注解明确标记资源和入口(或通过配置指定上下文),实现链路识别。

示例

@GetMapping("/create")
public Order createOrder(@RequestParam("userId") Long userId,@RequestParam("productId") Long productId) {return orderService.createOrder(userId, productId);
}@GetMapping("/seckill")
public Order seckill(@RequestParam(value = "userId" ) Long userId,@RequestParam(value = "productId") Long productId){Order order = orderService.createOrder(productId, userId);order.setId(Long.MAX_VALUE);return order;
}

配置文件添加web-context-unify: false

spring:cloud:sentinel:transport:# 指定Sentinel控制台地址dashboard: localhost:8080# 设置为true,表示启动时立即初始化Sentinel。eager: true# 关闭Web上下文统一(sentinel_spring_web_context)web-context-unify: falsefeign:sentinel:enabled: true

如果web-context-unify使用默认true,则会显示
在这里插入图片描述
点击/seckill下的createOrder
注意:启动Sentinel后需要执行一次代码才会显示
在这里插入图片描述
设置入口资源只对/seckill限制
在这里插入图片描述
访问两个接口时即可发现只有/seckill接口被限制
http://127.0.0.1:8081/create?userId=10&productId=11
http://127.0.0.1:8081/seckill?userId=10&productId=11

关联策略

触发逻辑

  • 与当前资源相关联的另一个资源的流量达到阈值时,对当前资源的请求进行限流。(即:B 资源流量过高时,限制 A 资源的请求,防止 A 资源进一步加剧 B 的压力)

场景

用于保护 “有依赖关系的资源”,避免因关联资源过载而引发连锁反应。如:

  • 数据库读写分离:当大量的写操作(关联资源A)达到阈值,可能拖慢数据库时,就限制读操作(资源B)的流量,保证写操作能正常完成。
  • 支付与查询:当支付接口(关联资源A)流量激增时,为了保证支付核心流程,可以适当限制订单查询接口(资源B)的流量。

特点

  • 限流的是 “当前资源”,但触发条件是 “关联资源” 的流量超标;
  • 适用于需要 “牺牲非核心资源保护核心资源” 的场景(如写操作通常比读操作更核心)。

示例

新增两个接口模拟读写分离场景

@GetMapping("/writeDb")
public String writeDb(){System.out.println("writeDb");return "writeDb success....";
}@GetMapping("/readDb")
public String readDb(){System.out.println("readDb");return "readDb success....";
}

在这里插入图片描述
先快速调用多次http://127.0.0.1:8081/writeDb
在调用http://127.0.0.1:8081/readDb
出现以下情况
在这里插入图片描述
注意:这里只有在调用writeDb接口超过阈值时,才会触发readDb接口的限制。只调用readDb接口不会触发

流控效果

流控效果是流量控制的 “执行动作”,当某个资源的流量达到预设阈值(如 QPS=100)时,Sentinel 会根据配置的流控效果对超额请求进行处理。其核心目标是:在保护系统不被过载的同时,最大化资源利用率,或保证请求处理的公平性。
在这里插入图片描述
注意:只有快速失败支持流控模式(直接、关联、链路)的设置
在这里插入图片描述

快速失败

核心思想

流量一旦达到阈值,立即拒绝后续所有请求。并抛出异常,不进行任何等待或缓冲。

适用场景

  • 对响应时间敏感的业务(如支付接口、核心交易链路),快速失败避免请求堆积,防止雪崩
  • 非核心业务,优先保证系统稳定性,牺牲部分请求可用性。

特点

  • 优点:处理速度快,对系统资源消耗低(无需维护队列或计时);
  • 缺点:可能导致短时间内大量请求失败,用户体验较差(如 “瞬间报错”)。

示例

设置规则
在这里插入图片描述
在代码中设置状态码为429,用于处理Sentinel限流或降级时的异常

import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.qf.common.R;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;import java.io.PrintWriter;/*** 用于处理Sentinel限流或降级时的异常*/
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {private ObjectMapper objectMapper = new ObjectMapper();@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response,String resourceName, BlockException e) throws Exception {response.setStatus(429); //too many requestsresponse.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();R error = R.error(500, resourceName + " 被Sentinel限制了,原因:" + e.getClass());String json = objectMapper.writeValueAsString(error);writer.write(json);writer.flush();writer.close();}
}

在这里插入图片描述
使用apipost进行压测
断言状态码为200成功
在这里插入图片描述
设置10个线程,发送5秒
在这里插入图片描述
这里可以看到成功请求数为11个
总结:快速失败会把多余的请求直接抛弃。

Warm Up(预热 / 冷启动)

核心思想

让系统从“冷”状态平滑地过渡到“全速”状态(热身),避免冷启动时瞬间高并发导致系统崩溃

适用场景

  • 系统刚启动(或重启)后,需要时间加载缓存、初始化连接池等资源(冷系统);
  • 流量波动较大的场景(秒杀/抢购系统),避免系统瞬间过载。

特点

  • 优点:保护系统不被突发流量冲击,让系统资源(如 CPU、内存)逐步提升负载;
  • 缺点:预热期间会有部分请求被限流,需要业务允许 “渐进式可用”。

为什么需要Warm Up?
系统在冷启动(如刚启动、长时间低负载后突然扩容)时,各种资源(如数据库连接池、缓存、JVM JIT编译)可能还未完全准备好。如果瞬间施加全部流量,很可能导致系统因负载过高而崩溃。Warm Up 给它一个“热身”的时间。

在这里插入图片描述

示例

在这里插入图片描述
效果:一开始只处理三分一的请求(1/10),之后每秒会逐步增加,三秒时和之后每秒处理10个请求
进行压测
查看接口日志

2025-02-25T07:49:36.499+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-4] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:36.500+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-17] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:36.499+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-6] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:37.000+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-20] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:37.000+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-18] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:37.000+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-17] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:38.000+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-2] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:38.000+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-8] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:38.000+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-19] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:38.000+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-11] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:38.000+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-14] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:38.000+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-18] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:39.000+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-9] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:39.000+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-19] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:39.000+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-20] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:39.000+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-2] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:39.000+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-8] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:39.000+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-1] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:39.000+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-14] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:39.000+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-3] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:39.000+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-16] com.qf.controller.OrderController        : ----------readDb----------
2025-02-25T07:49:39.000+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-5] com.qf.controller.OrderController        : ----------readDb----------

可以看到每秒访问接口数量在逐步增加,直到每秒10个

排队等待(Rate Limiting / Queueing)

核心思想

当流量超过阈值时,不立即拒绝请求,而是让超限的请求进入队列排队等待,以固定的速率(等于阈值)处理,使用的是漏桶算法的思想。

适用场景

  • 需要平滑流量的场景(如秒杀、定时任务触发的批量请求),用排队来缓冲流量,避免恢复瞬间被压垮。
  • 对请求延迟不敏感(异步),但要求 “最终处理” 的业务(如日志上报、数据同步)。

在这里插入图片描述

示例

当单机阈值设置为2时,表示每隔500ms才允许通过下一个请求。1000ms/2所得。
效果:每秒中处理两个请求,多余的请求进行排队,超过1秒(timeout)丢弃
在这里插入图片描述
注意:排队等待不支持流控模式中的关联和链路,配置了也不会起到效果
使用Apipost进行请求发送

2025-02-26T07:33:46.192+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-12] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:46.192+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-5] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:46.192+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-13] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:46.193+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-14] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:46.692+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-10] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:47.192+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-17] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:47.692+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-21] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:48.191+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-13] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:48.691+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-10] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:49.191+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-15] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:49.691+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-12] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:50.197+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-10] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:50.695+08:00  INFO 34312 --- [qf-service-order] [nio-8081-exec-7] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:51.192+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-17] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:51.691+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-13] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:52.191+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-25] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:52.234+08:00  WARN 34312 --- [qf-service-order] [io-8081-exec-25] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.context.request.async.AsyncRequestNotUsableException: ServletOutputStream failed to flush: java.io.IOException: Connection reset by peer]
2025-02-26T07:33:52.692+08:00  INFO 34312 --- [qf-service-order] [io-8081-exec-17] com.qf.controller.OrderController        : ----------readDb----------
2025-02-26T07:33:52.692+08:00  WARN 34312 --- [qf-service-order] [io-8081-exec-17] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.context.request.async.AsyncRequestNotUsableException: ServletOutputStream failed to flush: java.io.IOException: Connection reset by peer]

开头的情况属于正常,统计时需要有时间起点。开始统计后发现是每秒处理两个请求。
最后有两条WARN级别的日志,表示客户端提前终止了与服务器的连接,导致服务器无法完成响应的发送。新来的请求因为排不上队(集合满了)而被丢弃,导致客户端等待超时后断开连接。


http://www.dtcms.com/a/399961.html

相关文章:

  • 给你一个网站seo如何做百度ai人工智能
  • 网站建设实验步骤盘锦网站建设流程
  • UNet改进(40):CrossTemporalUNet在3D时序数据处理中的应用
  • 计算机组成原理:时序产生器和控制方式
  • 写作助手系统:AI辅助内容创作的技术实现
  • 网站开发完整视频网站做填充
  • 医院 网站后台管理asp网站建设外文参考文献
  • FMCW雷达:从理论到MATLAB GNU Radio双平台验证
  • 每日精讲:⼆叉树的构建及遍历/⼆叉树的前中后序遍历
  • 教人如何做吃的网站wordpress更改主题名
  • 网站和网页的区别在于o2o模式举例说明
  • 大概在网上建立一个网站一年要花多少钱呀微商网
  • 做网站服务好福州外贸网站建设推广
  • NAND FLASH与NOR FLASH
  • 有什么好的网站推荐一下私域流量运营
  • 新网站如何做排在前面给卖假性药的做网站一般要判多久
  • 臭氧传感器采用电化学原理测量原理一文浅淡
  • Spring-AI简单实践
  • [优选算法专题三二分查找——NO.18在排序数组中查找元素的第一个和最后一个位置]
  • 智能化住宅防盗报警系统设计(论文+源码)
  • 58同城网站建设案例购买网域名的网站好
  • 创意合肥网站建设网站后台ftp账户
  • 配置文件空密码与明文密码修复方案
  • 对网站开发的理解js做网站登录界面
  • 统计二级域名的网站流量有什么用龙岗公司网站
  • vivado进行zynq开发问题总结
  • 大气金融网站peise网站
  • 计算机网站建设职业群wordpress 批量修改字体
  • 湖南省金力电力建设有限公司 网站亚太建设科技信息研究院网站
  • 北京网站建设培训网站建设先进个人材料