06-Sentinel限流熔断应用实践

06-Sentinel限流熔断应用实践Sentinel 简介背景分析在我们日常生活中 经常会在淘宝 天猫 京东 拼多多等平台上参与商品的秒杀 抢购以及一些优惠活动 也会在节假日使用 12306 手机 APP 抢火车票 高铁票 甚至有时候还要帮助同事 朋友为他们家小孩拉投票 刷票 这些场景都无一例外的会引起服务器流量的暴涨 导致网页无法显示 APP 反应慢 功能无法正常运转 甚至会引起整个网站的崩溃 我们如何在这些业务流量变化无常的情况下 保证各种业务安全运营 系统在任何情况下都不会崩溃呢 我们可以在系统负载过高时 采用限流 降级和熔断 三种措施来保

Sentinel简介

背景分析

Sentinel概述

Sentinel核心分为两个部分:

  • 核心库(Java 客户端):能够运行于所有 Java 运行时环境,同时对Dubbo /Spring Cloud 等框架也有较好的支持。
  • 控制台(Dashboard):基于 Spring Boot 开发,打包后可以直接运行。

安装Sentinel服务

https://github.com/alibaba/Sentinel/releases 

第三步:在sentinel对应目录,打开命令行(cmd),启动运行sentinel

java -Dserver.port=8180 -Dcsp.sentinel.dashboard.server=localhost:8180 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar 

访问Sentinal服务

Sentinel限流入门

概述

我们系统中的数据库连接池,线程池,nginx的瞬时并发等在使用时都会给定一个限定的值,这本身就是一种限流的设计。限流的目的防止恶意请求流量、恶意攻击,或者防止流量超过系统峰值。

准备工作

第一步:Sentinel 应用于服务提供方(sca-provider),在服务提供方添加依赖如下:

<dependency> <groupId>com.alibaba.cloud 
     groupId> <artifactId>spring-cloud-starter-alibaba-sentinel 
      artifactId>  
       dependency> 

第二步:打开服务提供方配置文件bootstrap.yml,添加sentinel配置,代码如下:

spring: cloud: sentinel: transport: dashboard: localhost:8180 # 指定sentinel控制台地址。 

第三步:创建一个用于演示限流操作的Controller对象,例如:

package com.jt.provider.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/provider") public class ProviderSentinelController { 
    @GetMapping("/sentinel01") public String doSentinel01(){ 
    return "sentinel 01 test ..."; } } 

第三步:启动sca-provider服务,然后对指定服务进行访问,如图所示:

在这里插入图片描述

Sentinel的控制台其实就是一个SpringBoot编写的程序,我们需要将我们的服务注册到控制台上,即在微服务中指定控制台的地址,并且还要在消费端开启一个与sentinel控制台传递数据端的端口,控制台可以通过此端口调用微服务中的监控程序来获取各种信息。

Sentinel限流入门实践

我们设置一下指定接口的流控(流量控制),QPS(每秒请求次数)单机阈值为1,代表每秒请求不能超出1次,要不然就做限流处理,处理方式直接调用失败。

第二步:设置限流策略,如图所示:

在这里插入图片描述

第三步:反复刷新访问你的服务,检测是否有限流信息输出,如图所示:

在这里插入图片描述

小节面试分析

  • Sentinel是什么?(阿里推出一个流量控制平台,防卫兵)
  • 类似Sentinel的产品你知道有什么?(hystrix)
  • Sentinel是如何对请求进行限流的?(基于sentinel依赖提供的拦截器)
  • 你了解哪些限流算法?(计数器、令牌桶、漏斗算法,滑动窗口算法,…)
  • Sentinel 默认的限流算法是什么?(滑动窗口算法)

Sentinel流控规则分析

阈值类型

  • QPS(Queries Per Second):当调用相关url对应的资源时,QPS达到单机阈值时,就会限流。
  • 线程数:当调用相关url对应的资源时,线程数达到单机阈值时,就会限流。

设置限流模式

Sentinel的流控模式代表的流控的方式,默认【直接】,还有关联,链路。

直接模式

关联模式

当关联的资源达到指定阈值,就限流自己。例如设置了关联资源为ur2时,假如关联资源url2的qps阀值超过1时,就限流url1接口(是不是感觉很霸道,关联资源达到阀值,是本资源接口被限流了)。这种关联模式有什么应用场景呢?我们举个例子,订单服务中会有2个重要的接口,一个是读取订单信息接口,一个是写入订单信息接口。在高并发业务场景中,两个接口都会占用资源,如果读取接口访问过大,就会影响写入接口的性能。业务中如果我们希望写入订单比较重要,要优先考虑写入订单接口。那就可以利用关联模式;在关联资源上面设置写入接口,资源名设置读取接口就行了;这样就起到了优先写入,一旦写入请求多,就限制读的请求。例如

第一步:在ProviderSentinelController中添加一个方法,例如:

 @GetMapping("/sentinel02") public String doSentinel02(){ 
    return "sentinel 02 test ..."; } 

第二步:在sentinel中做限流设计,例如

在这里插入图片描述
第三步:打开两个测试窗口,对/provider/sentinel02进行访问,检查/provider/sentinel01的状态,例如:

在这里插入图片描述

链路模式

链路模式只记录指定链路入口的流量。也就是当多个服务对指定资源调用时,假如流量超出了指定阈值,则进行限流。被调用的方法用@SentinelResource进行注解,然后分别用不同业务方法对此业务进行调用,假如A业务设置了链路模式的限流,在B业务中是不受影响的。现在对链路模式做一个实践,例如:

例如现在设计一个业务对象,代码如下(为了简单,可以直接写在启动类内部):

第一步:在指定包创建一个ResourceService类,代码如下:

package com.jt.provider.service; @Service public class ResourceService{ 
    @SentinelResource("doGetResource") public String doGetResource(){ 
    return "doGetResource"; } } 

第二步:在ProviderSentinelController中添加两个方法(相当于两条链路),例如:

 @Autowired private ResourceService resourceService; @GetMapping("/sentinel03") public String doSentinel03(){ 
    resourceService.doGetResource(); return "sentinel 03 test"; } @GetMapping("/sentinel04") public String doSentinel04(){ 
    resourceService.doGetResource(); return "sentinel 04 test"; } 

第三步:在sentinel中配置限流规则,例如:

在这里插入图片描述

在这里插入图片描述

sentinel: web-context-unify: false 

我们也可以基于@SentinelResource注解描述的方法进行限流后的异常进行自定义处理,其步骤如下:

第一步:定义blockHandlerClass,例如:

package com.jt.provider.service; import com.alibaba.csp.sentinel.slots.block.BlockException; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @Slf4j @Component public class ResourceBlockHandler { 
    / * 限流后的异常处理方法,应用于@SentinelResource注解中, * 此方法在编写时有如下几个要求: * 1)方法修饰符为public * 2)必须为static方法 * 3)返回值类型与@SentinelResource注解描述的方法相同 * 4)参数类型为BlockException * 5)方法名自己定义 * @param ex * @return */ public static String doHandle(BlockException ex){ 
    log.error("block exception {}", ex.getMessage()); return "访问太频繁了,稍等片刻再访问"; } } 

第二步:修改@SentinelResource注解中的属性定义,例如:

@SentinelResource(value="doGetResource", blockHandlerClass = ResourceBlockHandler.class, blockHandler = "doHandle") public String doGetResource(){ 
    return "do get resource"; } 

第三步:在controller方法中,调用@Sentinel注解描述的方法,例如:

/ * 演示链路限流 * @return */ @GetMapping("/sentinel03") public String doSentinel03(){ 
    return resourceService.doGetResource(); //return "sentinel 03 test"; } 

小节面试分析

  • 你了解sentinel中的阈值应用类型吗?(两种-QPS,线程数)
  • Sentinel的限流规则中默认有哪些限流模式?(直连,关联,链路)
  • Sentinel的限流效果有哪些?(快速失败,预热,排队)

Sentinel降级应用实践

概述

准备工作

在ProviderController 类中添加doSentinel05方法,基于此方法演示慢调用过程下的限流,代码如下:

 //AtomicLong 类支持线程安全的自增自减操作 private AtomicLong atomicLong=new AtomicLong(1); @GetMapping("/sentinel05") public String doSentinel05() throws InterruptedException { 
    //获取自增对象的值,然后再加1 long num=atomicLong.getAndIncrement(); if(num%2==0){ 
   //模拟50%的慢调用比例 Thread.sleep(200); } return "sentinel 04 test"; } 

说明,我们在此方法中设置休眠,目的是为了演示慢调用(响应时间比较长).

Sentinel降级入门

第三步:对指定链路(例如http://localhost:8081/provider/sentinel05)进行访问刷新,多次访问测试,检测页面上是否会出现限流(底层默认的熔断异常为DegradeException),可以自己在异常处理器(假如是默认的,可在DefaultBlockExceptionHandler中加断点)中进行断点分析。

小节面试分析

  • 何为降级熔断?(让外部应用停止对服务的访问,生活中跳闸,路障设置-此路不通)
  • 为什么要进行熔断呢?(平均响应速度越来越慢或经常出现异常,这样可能会导致调用链堆积,最终系统崩溃)
  • Sentinel中限流,降级的异常父类是谁?(BlockException)
  • Sentinel 出现降级熔断时,系统底层抛出的异常是谁?(DegradeException)
  • Sentinel中异常处理接口是谁?(BlockExceptionHandler)
  • Sentinel中异常处理接口下默认的实现类为? (DefaultBlockExceptionHandler)
  • 假如Sentinel中默认的异常处理规则不满足我们的需求怎么办?(自己定义)
  • 我们如何自己定义Sentinel中异常处理呢?(直接或间接实现BlockExceptionHandler )
  • Sentinel熔断降级策略有哪些?(慢调用比例、异常比例、异常数)

Sentinel热点规则分析(重点)

概述

何为热点?热点即经常访问的数据。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制。
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制。

热点参数限流会统计传入参数中的热点数据,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。其中,Sentinel会利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。

快速入门

第一步:在sca-provider中的ResourceBlockHandler类中添加异常处理方法,例如:

public static String doHandle(Integer id,BlockException ex){ 
    log.error("被限流了.....,{}",ex); return "访问太频繁了...."; } 

第二步:在sca-provider中ResourceService类中添加基于id查询数据的业务方法,例如:

@SentinelResource(value="resource", blockHandlerClass = ResourceBlockHandler.class, blockHandler = "doHandle") public String doGetResource(Integer id){ 
    //.... return "the data's id is "+id; } 

第三步:在sca-provider中的ProviderSentinelController中添加如下方法,例如:

 @GetMapping("/sentinel/sentinel06") public String doFindById(@RequestParam("id") Integer id){ 
    return resourceService.doGetResource(id); } 
com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException: 2 

特定参数设计

热点参数其实说白了就是特殊的流控,我们还可以基于热点参数的具体值进行限流。可以通过配置参数例外项进行实现,我们现在来编辑一下热点规则,如图所示:

在这里插入图片描述
点击编辑后出现如下页面,然后添加参数例外项,例如:
在这里插入图片描述
其中,这里表示参数值为20时阈值为100,其它参数值阈值为1.






小节面试分析

  • 如何理解热点数据?(访问频度比较高的数据,某些商品、谋篇文章、某个视频)
  • 热点数据的限流规则是怎样的?(主要是针对参数进行限流设计)
  • 热点数据中的特殊参数如何理解?(热点限流中的某个参数值的阈值设计)
  • 对于热点数据的访问出现限流以后底层异常是什么?(ParamFlowException)

Sentinel系统规则(了解)

概述

系统在生产环境运行过程中,我们经常需要监控服务器的状态,看服务器CPU、内存、IO等的使用率;主要目的就是保证服务器正常的运行,不能被某些应用搞崩溃了;而且在保证稳定的前提下,保持系统的最大吞吐量。

快速入门

系统规则是一种全局设计规则,其中,

  • Load(仅对 Linux/Unix-like 机器生效):当系统 load1 超过阈值,且系统当前的并发线程数超过系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 计算得出。设定参考值一般是 CPU cores * 2.5。
  • CPU使用率:当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0)。
  • RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
  • 线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

说明,系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN),比如 Web 服务。

小节面试分析

  • 如何理解sentinel中的系统规则?(是对所有链路的控制规则,是一种系统保护策略)
  • Sentinel的常用系统规则有哪些?(RT,QPS,CPU,线程,Load-linux,unix)
  • Sentinel系统保护规则被触发以后底层会抛出什么异常?(SystemBlockException)

Sentinel授权规则(重要)

概述

很多时候,我们需要根据调用方来限制资源是否通过,这时候可以使用 Sentinel 的黑白名单控制的功能。黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。例如微信中的黑名单。

快速入门

  • 资源名:即限流规则的作用对象
  • 流控应用:对应的黑名单/白名单中设置的规则值,多个值用逗号隔开.
  • 授权类型:白名单,黑名单(不允许访问).

案例实现:

定义请求解析器,用于对请求进行解析,并返回解析结果,sentinel底层在拦截到用户请求以后,会对请求数据基于此对象进行解析,判定是否符合黑白名单规则,例如:

第一步:定义RequestOriginParser接口的实现类,在接口方法中解析请求参数数据并返回,底层会基于此返回值进行授权规则应用。

@Component public class DefaultRequestOriginParser implements RequestOriginParser { 
    @Override public String parseOrigin(HttpServletRequest request) { 
    String origin = request.getParameter("origin");//这里的参数名会与请求中的参数名一致 return origin; } } 

在这里插入图片描述

拓展:尝试基于请求ip等方式进行黑白名单的规则设计,例如:

第一步: 修改请求解析器,获取请求ip并返回,例如:

@Component public class DefaultRequestOriginParser implements RequestOriginParser { 
    //解析请求源数据 @Override public String parseOrigin(HttpServletRequest request) { 
    //获取访问请求中的ip地址,基于ip地址进行黑白名单设计(例如在流控应用栏写ip地址) String ip= request.getRemoteAddr(); System.out.println("ip="+ip); return ip; }//授权规则中的黑白名单的值,来自此方法的返回值 } 

小节面试分析

  • 如何理解Sentinel中的授权规则?(对指定资源的访问给出的一种简易的授权策略)
  • Sentinel的授权规则是如何设计的?(白名单和黑名单)
  • 如何理解Sentinel中的白名单?(允许访问的资源名单)
  • 如何理解Sentinel中的黑名单?(不允许访问的资源名单)、
  • Sentinel如何识别白名单和黑名单?(在拦截器中通过调用RequestOriginParser对象的方法检测具体的规则)
  • 授权规则中RequestOriginParser类的做用是什么?(对流控应用值进行解析,检查服务访问时传入的值是否与RequestOriginParser的parseOrigin方法返回值是否相同。)

总结(Summary)

总之,Sentinel可为秒杀、抢购、抢票、拉票等高并发应用,提供API接口层面的流量限制,让突然暴涨而来的流量用户访问受到统一的管控,使用合理的流量放行规则使得用户都能正常得到服务。

重难点分析

  • Sentinel诞生的背景?(计算机的数量是否有限,处理能力是否有限,并发比较大或突发流量比较大)
  • 服务中Sentinel环境的集成,初始化?(添加依赖-两个,sentinel配置)
  • Sentinel 的限流规则?(阈值类型-QPS&线程数,限流模式-直接,关联,链路)
  • Sentinel 的降级(熔断)策略?(慢调用,异常比例,异常数)
  • Sentinel 的热点规则设计(掌握)?
  • Sentinel 系统规则设计?(了解,全局规则定义,针对所有请求有效)
  • Sentinel 授权规则设计?(掌握,黑白名单)

FAQ分析

  • 为什么要限流?
  • 你了解的那些限流框架?(sentinel)
  • 常用的限流算法有那些?(计数,令牌桶-电影票,漏桶-漏斗,滑动窗口)
  • Sentinel有哪些限流规则?(QPS,线程数)
  • Sentinel有哪些限流模式?(直接,关联-创建订单和查询订单,链路限流-北京六环外不限号,但是五环就限号)
  • Sentinel 的降级(熔断)策略有哪些?(慢调用-响应时长,异常比例-异常占比,异常数)
  • Sentinel 的热点规则中的热点数据?(热卖商品,微博大咖,新上映的电影)
  • 如何理解Sentinel 授权规则中的黑白名单?

Bug分析

  • 依赖下载失败 (maven-本地库,网络,镜像仓库)
  • 单词错误(拼写错误)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/224022.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午12:52
下一篇 2026年3月17日 下午12:53


相关推荐

  • Java集合ArrayList和LinkedList区别

    Java集合ArrayList和LinkedList区别Java 的集合类主要由两个接口派生而出 Collection 和 Map Collection 和 Map 是 Java 集合框架的根接口 Java 集合大致可以分为 Set List Queue 和 Map 四种体系 其中 Set 代表无序 不可重复的集合 List 代表有序 重复的集合 而 Map 则代表具有映射关系的集合 Queue 体系集合 代表一种队列集合实现 jdk1 4 以前没有 Queue 集合 一般用 Linked

    2026年3月18日
    2
  • Protel 99SE详细安装教程(附安装包)[通俗易懂]

    Protel 99SE详细安装教程(附安装包)[通俗易懂]安装步骤:安装前先关闭杀毒软件和360卫士,注意安装路径不能有中文,安装包路径也不要有中文。安装前请断网。试装系统:win1064bit1.解压安装包。2.以管理员身份运行Protel99SE文件夹里的安装程序。3.点击下一步。4.name和company随便输入,打开SerialNO.txt,将serialNO输入到安装界面的code栏中。5.选择好安装目录(不要出现中…

    2022年5月30日
    85
  • Java 注解与反射

    Java 注解与反射

    2021年10月7日
    42
  • AI落地开源三剑客系列教程:工作流平台n8n使用教程

    AI落地开源三剑客系列教程:工作流平台n8n使用教程

    2026年3月13日
    2
  • Nginx 0.8.53 FastCGI参数详解

    Nginx 0.8.53 FastCGI参数详解来源地址:http://blog.csdn.net/eric1012/article/details/6075460以下配置都是基于Nginx0.8.53版本做解析。资源来源于个人翻译,网上摘录,如有错误信息地方,请提醒修正。本人已经制作PDF版本,可以直接下载查阅。 http://blogimg.chinaunix.net/blog/upfile2/101214

    2022年7月11日
    22
  • java中高级面试题总结(全面)_java面试题大全

    java中高级面试题总结(全面)_java面试题大全jvm结构原理,GC工作原理Jvm结构:Jvm主要包括四个部分:1、类加载器(ClassLoad)在JVM启动时或者在类运行时将需要的class加载到JVM中。类加载时间与过程:类从被加载到虚拟机内存开始,在到卸载出内存为止,正式生命周期包括了:加载,验证,准备,解析,初始化,使用和卸载7个阶段。其中验证、准备、解析这个三个步…

    2022年8月20日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号