1小时上手Alibaba Sentinel流控安全组件

news2024/11/24 20:38:22

在这里插入图片描述

微服务的雪崩效应
假如我们开发了一套分布式应用系统,前端应用分别向A/H/I/P四个服务发起调用请求:
在这里插入图片描述
但随着时间推移,假如服务 I 因为优化问题,导致需要 20 秒才能返回响应,这就必然会导致20秒内该请求线程会一直处于阻塞状态。
在这里插入图片描述
但是,如果这种状况放在高并发场景下,就绝对不允许出现,假如在 20 秒内有 10 万个请求通过应用访问到后端微服务。容器会因为大量请求阻塞积压导致连接池爆满,而这种情况后果极其严重. 轻则"服务无响应",重则前端应用直接崩溃。
以上这种因为某一个节点长时间处理导致应用请求积压崩溃的现象被称为微服务的"雪崩效应"。
在这里插入图片描述
如何有效避免雪崩效应?
刚才我们分析了雪崩现象,是因为出现瞬间大流量+微服务响应慢造成的.针对这两点在架构设计时要采用不同方案:
● 采用限流方式进行预防:可以采用限流方案,控制请求的流入,让流量有序的进入应用,保证流量在一个可控的范围内
● 采用服务降级与熔断进行补救:针对响应慢问题,可以采用服务降级与熔断进行补救
以下图为例,在用户支付完成后,通过消息通知服务向用户邮箱发送"订单已确认"的邮件, 但假设消息通知服务出现异常需要10秒钟才能完成发送请求, 这是不能接受的。为了预防雪崩,我们可以在微服务体系中增加服务降级的功能,预设2秒钟有效期,如遇延迟变最多允许2秒,2秒内服务未处理完成则直接降级并返回响应,此时支付服务会收到"邮件发送超时"的错误信息。这也就意味着消息通知服务最多只能有两秒钟的处理时间,要么发送成功,要么超时降级。 因此阻塞时间缩短,产生雪崩的概率会大大降低。
在这里插入图片描述
Alibaba Sentinel 介绍
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
https://sentinelguard.io/
在这里插入图片描述
演示用的单机版
https://hub.docker.com/r/bladex/sentinel-dashboard
用户名:sentinel/密码:sentinel
在这里插入图片描述
我准备好的docker-compose脚本

rm -rf /etc/sca/sentinel-nacos-config
mkdir -p /etc/sca
cd /etc/sca
wget http://manongbiji.oss-cn-beijing.aliyuncs.com/ittailkshow/sca2023/download/sentinel-nacos-config.zip -O sentinel-nacos-config.zip
unzip sentinel-nacos-config.zip
cd sentinel-nacos-config
docker-compose up -d

接入过程
pom依赖

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

application.yml

spring:
  application:
    name: sentinel-sample
  cloud:
    sentinel:
      transport:
        dashboard: 192.168.31.233:8858
      eager: true
    nacos:
      server-addr: 192.168.31.231:8848
      username: nacos
      password: nacos
  jackson:
    default-property-inclusion: non_null
server:
  port: 80
logging:
  level:
    root: info

其他不需要任何调整
在Sentinel为/test_flow_rule分配QPS阈值
在这里插入图片描述
实施限流
在这里插入图片描述
在这里插入图片描述
Sentinel工作主流程
在 Sentinel 里面,所有的资源都对应一个资源名称以及一个 Entry。Entry 可以通过对主流框架的适配自动创建,也可以通过注解的方式或调用 API 显式创建;每一个 Entry 创建的时候,同时也会创建一系列功能插槽(slot chain)。这些插槽有不同的职责,例如:
● NodeSelectorSlot 负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降级;
● ClusterBuilderSlot 则用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count 等等,这些信息将用作为多维度限流,降级的依据;
● StatisticSlot 则用于记录、统计不同纬度的 runtime 指标监控信息;
● FlowSlot 则用于根据预设的限流规则以及前面 slot 统计的状态,来进行流量控制;
● AuthoritySlot 则根据配置的黑白名单和调用来源信息,来做黑白名单控制;
● DegradeSlot 则通过统计信息以及预设的规则,来做熔断降级;
● SystemSlot 则通过系统的状态,例如 load1 等,来控制总的入口流量;
在这里插入图片描述
ContextUtil.enter(“entrance1”, “appA”); Entry nodeA = SphU.entry(“nodeA”); if (nodeA != null) { nodeA.exit(); } ContextUtil.exit(); machine-root / / EntranceNode1 / / DefaultNode(nodeA)ContextUtil.enter(“entrance1”, “appA”); Entry nodeA = SphU.entry(“nodeA”); if (nodeA != null) { nodeA.exit(); } ContextUtil.exit(); ContextUtil.enter(“entrance2”, “appA”); nodeA = SphU.entry(“nodeA”); if (nodeA != null) { nodeA.exit(); } ContextUtil.exit(); machine-root / \ / \ EntranceNode1 EntranceNode2 / \ / \ DefaultNode(nodeA) DefaultNode(nodeA)EntranceNode: machine-root(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:12 1mb:0 1mt:12) -EntranceNode: sentinel_web_servlet_context(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:12 1mb:0 1mt:12) --/app/briefinfos.json(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:0 1mb:0 1mt:0) --/resource/machineResource.json(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:0 1mb:0 1mt:0) --/auth/login(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:0 1mb:0 1mt:0) --/version(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:0 1mb:0 1mt:0) --/(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:0 1mb:0 1mt:0) --/registry/machine(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:12 1mb:0 1mt:12) --/metric/queryTopResourceMetric.json(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:0 1mb:0 1mt:0) --/app/sentinel-sample/machines.json(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:0 1mb:0 1mt:0) -EntranceNode: sentinel_default_context(t:0 pq:0.0 bq:0.0 tq:0.0 rt:0.0 prq:0.0 1mp:0 1mb:0 1mt:0) t:threadNum pq:passQps bq:blockQps tq:totalQps rt:averageRt prq: passRequestQps 1mp:1m-pass 1mb:1m-block 1mt:1m-totalid: nodeA idx origin threadNum passedQps blockedQps totalQps aRt 1m-passed 1m-blocked 1m-total 1 caller1 0 0 0 0 0 0 0 0 2 caller2 0 0 0 0 0 0 0 0
总体的框架如下:
在这里插入图片描述
Sentinel为springboot程序提供了一个starter依赖,由于sentinel starter依赖默认情况下就会为所有的HTTP服务提供限流埋点,所以在springboot 中的Controller都可以受到Sentinel的保护;
只需为应用添加 spring-cloud-starter-alibaba-sentinel 依赖,所有的HTTP接口都能获得Sentinel保护,当然,我们还需要为Sentinel配置保护的规则;
底层通过一个拦截器对请求url进行拦截:
com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebInterceptor
Sentinel 将 ProcessorSlot 作为 SPI 接口进行扩展(1.7.2 版本以前 SlotChainBuilder 作为 SPI),使得 Slot Chain 具备了扩展的能力。您可以自行加入自定义的 slot 并编排 slot 间的顺序,从而可以给 Sentinel 添加自定义的功能。
在这里插入图片描述
关键Slot的设计
NodeSelectorSlot
这个 slot 主要负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降级。
上述代码通过ContextUtil.enter()创建了一个名为entrance1的上下文,同时指定调用发起者为appA;接着通过SphU.entry()请求一个 token,如果该方法顺利执行没有抛BlockException,表明 token 请求成功。
以上代码将在内存中生成以下结构:
注意:每个DefaultNode由资源 ID 和输入名称来标识。换句话说,一个资源 ID 可以有多个不同入口的 DefaultNode。
以上代码将在内存中生成以下结构:Entrance
上面的结构可以通过调用http://192.168.31.233:8719/tree?type=root来显示:
ClusterBuilderSlot
此插槽用于构建资源的ClusterNode以及调用来源节点。ClusterNode保持资源运行统计信息(响应时间、QPS、block 数目、线程数、异常数等)以及原始调用者统计信息列表。来源调用者的名字由ContextUtil.enter(contextName,origin)中的origin标记。可通过如下命令查看某个资源不同调用者的访问情况:curl http://localhost:8719/origin?id=caller:
StatisticSlot
StatisticSlot是 Sentinel 的核心功能插槽之一,用于统计实时的调用数据。
● clusterNode:资源唯一标识的 ClusterNode 的 runtime 统计
● origin:根据来自不同调用者的统计信息
● defaultnode: 根据上下文条目名称和资源 ID 的 runtime 统计
● 入口的统计
Sentinel 底层采用高性能的滑动窗口数据结构LeapArray来统计实时的秒级指标数据,可以很好地支撑写多于读的高并发场景。
在这里插入图片描述
FlowSlot
这个 slot 主要根据预设的资源的统计信息,按照固定的次序,依次生效。如果一个资源对应两条或者多条流控规则,则会根据如下次序依次检验,直到全部通过或者有一个规则生效为止:
● 指定应用生效的规则,即针对调用方限流的;
● 调用方为 other 的规则;
● 调用方为 default 的规则。
DegradeSlot
这个 slot 主要针对资源的平均响应时间(RT)以及异常比率,来决定资源是否在接下来的时间被自动熔断掉。
SystemSlot
这个 slot 会根据对于当前系统的整体情况,对入口资源的调用进行动态调配。其原理是让入口的流量和当前系统的预计容量达到一个动态平衡。
注意系统规则只对入口流量起作用(调用类型为 EntryType.IN),对出口流量无效。可通过 SphU.entry(res, entryType) 指定调用类型,如果不指定,默认是EntryType.OUT。
流量控制
流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状,如下图所示:
在这里插入图片描述
流量控制有以下几个角度:
● 资源的调用关系,例如资源的调用链路,资源和资源之间的关系;
● 运行指标,例如 QPS、线程池、系统负载等;
● 控制的效果,例如直接限流、冷启动、排队等。
curl http://localhost:8719/cnode?id=resourceNameidx id thread pass blocked success total Rt 1m-pass 1m-block 1m-all exeption 2 abc647 0 46 0 46 46 1 2763 0 2763 0curl http://192.168.31.230:8719/origin?id=nodeAid: nodeA idx origin threadNum passedQps blockedQps totalQps aRt 1m-passed 1m-blocked 1m-total 1 caller1 0 0 0 0 0 0 0 0 2 caller2 0 0 0 0 0 0 0 0 machine-root / \ / \ Entrance1 Entrance2 / \ / \ DefaultNode(nodeA) DefaultNode(nodeA)
Sentinel 的设计理念是让您自由选择控制的角度,并进行灵活组合,从而达到想要的效果。
流量控制
FlowSlot 会根据预设的规则,结合前面 NodeSelectorSlot、ClusterNodeBuilderSlot、StatistcSlot 统计出来的实时信息进行流量控制。
限流的直接表现是在执行 Entry nodeA = SphU.entry(资源名字) 的时候抛出 FlowException 异常。FlowException 是 BlockException 的子类,您可以捕捉 BlockException 来自定义被限流之后的处理逻辑。
同一个资源可以对应多条限流规则。FlowSlot 会对该资源的所有限流规则依次遍历,直到有规则触发限流或者所有规则遍历完毕。
一条限流规则主要由下面几个因素组成,我们可以组合这些元素来实现不同的限流效果:
● resource:资源名,即限流规则的作用对象
● count: 限流阈值
● grade: 限流阈值类型,QPS 或线程数
● strategy: 根据调用关系选择策略
在这里插入图片描述
基于QPS/并发数的流量控制
流量控制主要有两种统计类型,一种是统计线程数,另外一种则是统计 QPS。类型由 FlowRule.grade 字段来定义。其中,0 代表根据并发数量来限流,1 代表根据 QPS 来进行流量控制。其中线程数、QPS 值,都是由 StatisticSlot 实时统计获取的。
可以通过下面的命令查看实时统计信息:
输出内容格式如下:
其中:
● thread: 代表当前处理该资源的线程数;
● pass: 代表一秒内到来到的请求;
● blocked: 代表一秒内被流量控制的请求数量;
● success: 代表一秒内成功处理完的请求;
● total: 代表到一秒内到来的请求以及被阻止的请求总和;
● RT: 代表一秒内该资源的平均响应时间;
● 1m-pass: 则是一分钟内到来的请求;
● 1m-block: 则是一分钟内被阻止的请求;
● 1m-all: 则是一分钟内到来的请求和被阻止的请求的总和;
● exception: 则是一秒内业务本身异常的总和。
并发线程数流量控制
线程数限流用于保护业务线程数不被耗尽。例如,当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延迟增加,对于调用者来说,意味着吞吐量下降和更多的线程数占用,极端情况下甚至导致线程池耗尽。为应对高线程占用的情况,业内有使用隔离的方案,比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢(线程池隔离),或者使用信号量来控制同时请求的个数(信号量隔离)。这种隔离方案虽然能够控制线程数量,但无法控制请求排队时间。当请求过多时排队也是无益的,直接拒绝能够迅速降低系统压力。Sentinel线程数限流不负责创建和管理线程池,而是简单统计当前请求上下文的线程个数,如果超出阈值,新的请求会被立即拒绝。
QPS流控效果
当 QPS 超过某个阈值的时候,则采取措施进行流量控制。流量控制的手段包括下面 3 种,对应 FlowRule 中的 controlBehavior 字段:
● 直接拒绝(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)方式。该方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。具体的例子参见 FlowqpsDemo。
● 冷启动(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式。该方式主要用于系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮的情况。具体的例子参见 WarmUpFlowDemo。
通常冷启动的过程系统允许通过的 QPS 曲线如下图所示:
在这里插入图片描述
● 匀速器(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式。这种方式严格控制了请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。具体的例子参见 PaceFlowDemo。
该方式的作用如下图所示:
在这里插入图片描述
这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。
基于调用关系的流量控制
调用关系包括调用方、被调用方;方法又可能会调用其它方法,形成一个调用链路的层次关系。Sentinel 通过 NodeSelectorSlot 建立不同资源间的调用的关系,并且通过 ClusterNodeBuilderSlot 记录每个资源的实时统计信息。
有了调用链路的统计信息,我们可以衍生出多种流量控制手段。
根据调用方限流
ContextUtil.enter(resourceName, origin) 方法中的 origin 参数标明了调用方身份。这些信息会在 ClusterBuilderSlot 中被统计。可通过以下命令来展示不同的调用方对同一个资源的调用数据:
调用数据示例:
上面这个命令展示了资源名为 nodeA 的资源被两个不同的调用方调用的统计。
限流规则中的 limitApp 字段用于根据调用方进行流量控制。该字段的值有以下三种选项,分别对应不同的场景:
● default:表示不区分调用者,来自任何调用者的请求都将进行限流统计。如果这个资源名的调用总和超过了这条规则定义的阈值,则触发限流。
● {some_origin_name}:表示针对特定的调用者,只有来自这个调用者的请求才会进行流量控制。例如 NodeA 配置了一条针对调用者caller1的规则,那么当且仅当来自 caller1 对 NodeA 的请求才会触发流量控制。
● other:表示针对除 {some_origin_name} 以外的其余调用方的流量进行流量控制。例如,资源NodeA配置了一条针对调用者 caller1 的限流规则,同时又配置了一条调用者为 other 的规则,那么任意来自非 caller1 对 NodeA 的调用,都不能超过 other 这条规则定义的阈值。
同一个资源名可以配置多条规则,规则的生效顺序为:{some_origin_name} > other > default
根据调用链路入口限流:链路限流
NodeSelectorSlot 中记录了资源之间的调用链路,这些资源通过调用关系,相互之间构成一棵调用树。这棵树的根节点是一个名字为 machine-root 的虚拟节点,调用链的入口都是这个虚节点的子节点。
一棵典型的调用树如下图所示:
上图中来自入口 Entrance1 和 Entrance2 的请求都调用到了资源 NodeA,Sentinel 允许只根据某个入口的统计信息对资源限流。比如我们可以设置 FlowRule.strategy 为 RuleConstant.CHAIN,同时设置 FlowRule.ref_identity 为 Entrance1 来表示只有从入口 Entrance1 的调用才会记录到 NodeA 的限流统计当中,而对来自 Entrance2 的调用漠不关心。
调用链的入口是通过 API 方法 ContextUtil.enter(name) 定义的。
具有关系的资源流量控制:关联流量控制
当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写得速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。可使用关联限流来避免具有关联关系的资源之间过度的争抢,举例来说,read_db 和 write_db 这两个资源分别代表数据库读写,我们可以给 read_db 设置限流规则来达到写优先的目的:设置 FlowRule.strategy 为 RuleConstant.RELATE 同时设置 FlowRule.ref_identity 为 write_db。这样当写库操作过于频繁时,读数据的请求会被限流。
在这里插入图片描述
除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。
在这里插入图片描述
现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。
注意:本文档针对 Sentinel 1.8.0 及以上版本。1.8.0 版本对熔断降级特性进行了全新的改进升级,请使用最新版本以更好地利用熔断降级的能力。
熔断策略
Sentinel 提供以下几种熔断策略:
在这里插入图片描述
异常比例 (ERROR_RATIO)
当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
在这里插入图片描述
开启条件: 1秒钟内,有1个(最小请求数)list请求,便开启熔断检查
触发熔断: 当前秒,有超过50%(比例阈值)的请求产生异常触发熔断,之后5秒钟(熔断时长)所有请求被BLOCKED,5秒后半开状态检查
异常数是指在1分钟内异常的数量超过阈值则触发熔断。
● 慢调用比例 (SLOW_REQUEST_RATIO)
选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
在这里插入图片描述
开启条件: 1秒钟内,有1个(最小请求数)list接口请求,便开启熔断检查
触发熔断: 当前秒,有超过50%(比例阈值)的请求超过1ms(最大RT),如:3次里面有2次(75%)超过1ms, 触发熔断,之后5秒钟(熔断时长)所有请求被BLOCKED,5秒后半开状态检查
● 异常数 (ERROR_COUNT)
当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
在这里插入图片描述
开启条件: 当前秒有1个list接口请求,便开启熔断检查
触发熔断: 1分钟内list接口调用异常数大于100次触发熔断,之后80秒所有请求被BLOCKED,80秒后半开状态检查。
熔断降级规则说明
熔断降级规则(DegradeRule)包含下面几个重要的属性:
在这里插入图片描述
在这里插入图片描述
[ { “resource”:“/test_flow_rule”, “limitApp”:“default”, “grade”:1, “count”:2, “strategy”:0, “controlBehavior”:0, “clusterMode”:false } ][{ “resource”: “/test_degrade_rule”, “limitApp”: “default”, “grade”: 1, “count”: 0.2, “timeWindow”: 10, “minRequestAmount”: 5 }] com.alibaba.cloud spring-cloud-starter-alibaba-sentinel com.alibaba.csp sentinel-datasource-nacos org.springframework.boot spring-boot-starter-actuator spring: application: name: sentinel-sample cloud: sentinel: transport: dashboard: 192.168.31.233:8858 eager: true datasource: flow: nacos: server-addr: ${spring.cloud.nacos.server-addr} dataId: ${spring.application.name}-flow-rules groupId: SAMPLE_GROUP rule-type: flow username: nacos password: nacos degrade: nacos: server-addr: ${spring.cloud.nacos.server-addr} dataId: ${spring.application.name}-degrade-rules groupId: SAMPLE_GROUP rule-type: degrade nacos: server-addr: 192.168.31.231:8848 username: nacos password: nacos jackson: default-property-inclusion: non_null server: port: 80 logging: level: root: info management: endpoints: web: #将所有可用的监控指标项对外暴露 exposure: #可以访问 /actuator/sentinel进行查看Sentinel监控项 include: ‘*’// 20230416204036 // http://localhost/actuator/sentinel { “appName”: “sentinel-sample”, “consoleServer”: [ { “protocol”: “HTTP”, “host”: “192.168.31.233”, “port”: 8858 } ], “coldFactor”: “3”, “rules”: { “systemRules”: [ ], “authorityRule”: [ ], “paramFlowRule”: [ ], “flowRules”: [ { “resource”: “/test_flow_rule”, “limitApp”: “default”, “grade”: 1, “count”: 2.0, “strategy”: 0, “controlBehavior”: 0, “warmUpPeriodSec”: 10, “maxQueueingTimeMs”: 500, “clusterMode”: false } ], “degradeRules”: [ { “resource”: “/test_degrade_rule”, “limitApp”: “default”, “grade”: 1, “count”: 0.2, “timeWindow”: 10, “minRequestAmount”: 5, “slowRatioThreshold”: 1.0, “statIntervalMs”: 1000 } ] }, “metricsFileCharset”: “UTF-8”, “filter”: { “order”: -2147483648, “urlPatterns”: [ “/**” ], “enabled”: true }, “totalMetricsFileCount”: 6, “datasource”: { “degrade”: { “nacos”: { “dataType”: “json”, “ruleType”: “DEGRADE”, “serverAddr”: “192.168.31.231:8848”, “groupId”: “SAMPLE_GROUP”, “dataId”: “sentinel-sample-degrade-rules” } }, “flow”: { “nacos”: { “dataType”: “json”, “ruleType”: “FLOW”, “serverAddr”: “192.168.31.231:8848”, “username”: “nacos”, “password”: “nacos”, “groupId”: “SAMPLE_GROUP”, “dataId”: “sentinel-sample-flow-rules” } } }, “clientIp”: “192.168.31.2”, “clientPort”: “8719”, “logUsePid”: false, “metricsFileSize”: 52428800, “logDir”: “C:\Users\admin\logs\csp\”, “heartbeatIntervalMs”: 10000 }
生产环境
流控规则

DataId: sentinel-sample-flow-rules
Group: SAMPLE_GROUP
这段配置是用来配置 Alibaba Sentinel 流量控制规则的,具体解释如下:
● resource: 表示要进行流量控制的资源,本例中为 “/test_flow_rule”,也就是对 “/test_flow_rule” 的访问进行流量控制;
● limitApp: 表示流量控制的针对范围,这里设置为 “default”,表示针对默认组的应用进行流量控制;
● grade: 表示流量控制的维度
○ 0 代表根据并发数量来限流
○ 1 代表根据 QPS 来进行流量控制
● count: 表示允许通过的请求数,这里设置为 2,表示当 “/test_flow_rule” 的请求超过 2 次时,将触发流量控制;
● strategy: 表示流量控制的策略
○ 0-直接
○ 1-关联
○ 2-链路
● controlBehavior: 表示流量控制的行为
○ 0-快速失败
○ 1-Warm UP
○ 2-排队等待
● clusterMode: 表示是否使用集群模式,这里设置为 false,表示不使用集群模式。
熔断降级规则
sentinel-sample-degrade-rules
SAMPLE_GROUP
这段配置是用来配置 Alibaba Sentinel 熔断降级规则的,具体解释如下:
● resource: 表示要进行熔断降级控制的资源,本例中为 “/test_degrade_rule”,也就是对 “/test_degrade_rule” 的访问进行熔断降级控制;
● limitApp: 表示熔断降级控制的针对范围,这里设置为 “default”,表示针对默认组应用进行熔断降级控制;
● grade: 表示熔断降级控制的维度
○ 0-慢调用比例
○ 1-异常比例
○ 2-异常数策略
● count: 代表20%异常比例
● timeWindow: 表示熔断时长10秒
● minRequestAmount: 表示在熔断前必须在时间窗口内通过的请求次数,本例中设置为 5;
接入过程
● spring-cloud-starter-alibaba-sentinel :sentinel客户端
● sentinel-datasource-nacos:nacos配置中心集成组件
● spring-boot-starter-actuator:Spring Boot可观测性端点
application.yml
增加三组配置项
● spring.cloud.sentinel.datasource.flow 流控规则
● spring.cloud.sentinel.datasource.degrade熔断降级规则
● management.endpoints.web.exposure.include放行sentinel端点便于调试
启动应用确认已加载
http://localhost/actuator/sentinel
sentinel-nacos-config.zip

package com.itlaoqi.sentinelnacosconfig.config;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itlaoqi.sentinelnacosconfig.controller.ResponseObject;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

@Component
public class UrlBlockHandler implements BlockExceptionHandler {
    /**
     * RESTFul异常信息处理器      * @param httpServletRequest      * @param httpServletResponse      * @param e      * @throws Exception
     */
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
        String msg = null;
        if (e instanceof FlowException) {
            //限流异常       
            msg = "接口已被限流";
        } else if (e instanceof DegradeException) {
            //熔断异常           
            msg = "接口已被熔断,请稍后再试";
        } else if (e instanceof ParamFlowException) {
            //热点参数限流            
            msg = "热点参数限流";
        } else if (e instanceof SystemBlockException) {
            //系统规则异常         
            msg = "系统规则(负载/....不满足要求)";
        } else if (e instanceof AuthorityException) {
            //授权规则异常         
            msg = "授权规则不通过";
        }
        httpServletResponse.setStatus(500);
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setContentType("application/json;charset=utf-8");         //ObjectMapper是内置Jackson的序列化工具类,这用于将对象转为JSON字符串         ObjectMapper mapper = new ObjectMapper();         //某个对象属性为null时不进行序列化输出         mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);         mapper.writeValue(httpServletResponse.getWriter(),                 new ResponseObject(e.getClass().getSimpleName(), msg)         );     } }{     code: "FlowException",     message: "接口已被限流" }{     code: "DegradeException",     message: "接口已被熔断,请稍后再试" }
    }
}
}

丑陋的Sentinel默认异常提示
在这里插入图片描述
通过实现BlockExceptionHandler自定义异常输出
BlockExceptionHandler.handle()方法第三个参数类型是BlockException,它有五种子类代表不同类型的规则异常:
FlowException:流控规则异常。
DegradeException:熔断规则异常。
ParamFlowException:热点参数规则异常。
例如:针对id=5的冷门商品编号时不开启限流,针对id=10的热门商品编号则需要进行限流,当10号商品被限流时抛出热点参数异常。
SystemBlockException:系统规则异常。
例如:服务器CPU负载超过80%,抛出系统规则异常。
AuthorityException:授权规则异常。
例如:某个IP被列入黑名单,该IP在访问时就会抛出授权规则异常。
我们利用instanceof关键字确定具体的规则异常后,便通过response响应对象将封装好的ResponseObject对象返回给应用前端,此时响应中code值不再为0,而是对应的异常类型。
例如,当RESTful触发流控规则后,前端响应如下:
当触发熔断规则后,前端响应如下:
通过这种统一而通用的异常处理机制,对RESTful屏蔽了sentinel-core默认的错误文本,让项目采用统一的JSON规范进行输出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1941940.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Prompt Enginnering(提示工程)

什么是提示工程 prompt enginnering是提示工程的意思&#xff0c;也有叫指令工程。 用白话讲&#xff1a;是我们对GPT说出的话&#xff0c;我们向它提问的信息&#xff0c;就是prompt。 官方一点&#xff1a;是我们使用自然语言提示来控制和优化生成式模型&#xff08;生成式…

《Milvus Cloud向量数据库指南》——SPLADE:基于BERT的Learned稀疏向量技术深度解析

在自然语言处理(NLP)领域,随着深度学习技术的飞速发展,预训练语言模型如BERT(Bidirectional Encoder Representations from Transformers)已成为推动研究与应用进步的重要基石。BERT通过其强大的上下文感知能力,在多项NLP任务中取得了显著成效,尤其是在文本表示和语义理…

深入理解Linux网络(五):TCP接收唤醒

深入理解Linux网络&#xff08;五&#xff09;&#xff1a;TCP接收唤醒 TCP接收唤醒由软中断提供服务。 软中断&#xff08;也就是 Linux ⾥的 ksoftirqd 进程&#xff09;⾥收到数据包以后&#xff0c;发现是 tcp 的包的话就会执⾏到 tcp_v4_rcv 函数。接着如果是 ESTABLISH…

GMSSL2.x编译鸿蒙静态库和动态库及使用

一、编译环境准备 1.1 开发工具 DevEco-Studio下载。 1.2 SDK下载 ​ 下载编译第三方库的SDK有两种方式&#xff0c;第一种方式从官方渠道根据电脑系统选择对应的SDK版本&#xff0c;第二种方式通过DevEco-Studio下载SDK。本文只介绍通过DevEco-Studio下载SDK的方式。 安装…

(十一)Spring教程——Bean基本配置与依赖注入之属性注入

1.Bean基本配置 在进行Bean配置的详细讲解之前&#xff0c;先来了解以下Bean配置的基础知识&#xff0c;以快速建立起Bean配置的初步概念。 1.1装配一个Bean 在Spring容器的配置文件中定义一个简要Bean的配置片段如下所示 <bean id”foo” class”com.smart.Foo”/> 一般…

【VSCode】安装 【ESP-IDF】插件及【ESP32-S3】新建工程和工程配置

一、搭建基础工程 二、基础工程的文件架构解析 三、调试相关工具介绍 1、串口下载2、JTAG 下载与调试 四、工程的文件架构解析 五、基础工程配置 一、搭建基础工程 在 VS Code 中新建 ESP-IDF 基础工程的步骤如下&#xff1a; 1、启动 VS Code 并打开命令面板 按下“Ctrl…

AI+BI结合,数据分析新方向 —— 奥威BI数据可视化引领未来

【AIBI结合&#xff0c;数据分析新方向 —— 奥威BI数据可视化引领未来】 在数字化浪潮汹涌的今天&#xff0c;企业对于数据的洞察力与决策效率的需求日益增长。奥威BI&#xff08;Business Intelligence&#xff09;数据可视化解决方案&#xff0c;以其独特的“AIBI”融合创新…

压缩视频在线免费 怎么免费压缩视频大小 哪个软件可以免费压缩视频

在数字媒体时代&#xff0c;视频文件的体积越来越大&#xff0c;这就需要我们找到高效的方式来压缩视频&#xff0c;以节省存储空间和提升分享速度。本文将为您介绍几款免费的视频压缩软件&#xff0c;帮助您轻松应对视频文件管理难题。 方法一、 安装并打开一款的视频软件。 …

通过iframe嵌套的不同域名的页面之间处理cookie存储失败的问题——js技能提升

最近同事在写mvc的后台管理系统&#xff0c;通过iframe实现不同域名的页面的嵌套。 但是有个问题&#xff0c;就是从父页面打开iframe的子页面时&#xff0c;需要登录子页面&#xff0c;此时需要将子页面登录后的token存储到子页面的cookie中&#xff0c;方便子页面的其他接口…

Python 全栈体系【三阶】(三)

第一章 Django 七、静态文件 1. 概述 静态文件是指在WEB应用中的图像文件、CSS文件、Javascript文件。 2. 静态文件的配置 settings.py中关于静态文件的配置如下&#xff1a; STATICFILES_DIRS [BASE_DIR , static, ]STATIC_URL /static/其中&#xff1a; STATICFILES…

Vue 3 + Vite 项目中安装 Tailwind CSS

官网&#xff1a;安装 - TailwindCSS中文文档 | TailwindCSS中文网 tips&#xff1a;只按照官网的配置可能会导致样式不加载/加载不生效的问题 1、正确安装指令 npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p 自动生成 ​tailwind.config.js​…

鱼眼摄像头-opencv校准(基于棋盘+畸变表)

一&#xff1a;主要参数说明 1&#xff1a;内参矩阵K 是3*3的矩阵&#xff0c;其类似格式 Knp.array([ [389.2109574522624, 0.0, 630.2525667489842], [0.0, 388.505701978078, 360.7886749292513], [0.0, 0.0, 1.0]]) 2&#xff1a;畸变系数 针对鱼眼相机&#xff1a;…

DVWA靶场超(详细教程)--跨站攻击(XSS+CSRF)

一、XSS 反射型xss 打开dvwa的Reflected Cross Site Scripting (XSS) &#xff08;1&#xff09;low等级 查看页面源码&#xff08;ctrlu&#xff09;该界面有提交按钮和输入框 在输入框随便输入点字符&#xff0c;点击提交 可以看见输入的helloword嵌入到界面中。 View sou…

MybatisPlus的使用与详细讲解

今天我们来讲解一下Mybatis的升级版&#xff0c;就是MybatisPlus. MybatisPlus是如何获取实现CRUD的数据库表信息的&#xff1f; 默认以类名驼峰转下划线作为表名 默认把名为id的字段作为主键 默认把变量名驼峰转下划线作为表的字段名 1.MybatisPlus中比较常见的注解 TableN…

红人点集登录逆向+接口逆向:SHA256算法和Webpack反爬

&#x1f50d; 引言 红人点集采取了一系列加密和限制措施&#xff0c;主要是对于参数加密和登录token加密。今天利用Python与JavaScript逆向工程技术&#xff0c;实现逆向登录然后请求接口获取数据。 &#x1f50d; 思路与步骤详解 &#x1f527; 解密登录接口参数&#xf…

安防视频监控EasyCVR视频汇聚平台修改配置后无法启动的原因排查与解决

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台基于云边端一体化架构&#xff0c;兼容性强、支持多协议接入&#xff0c;包括国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤石云SD…

【Echarts示例】类甘特图的时间线图表

[示例] 类甘特图的时间线图表 const data [{ name: 预备阶段, start: 0, end: 2 },{ name: 战略展开, start: 2, end: 4 },{ name: 指挥所启动, start: 4, end: 6 },{ name: 电子对抗准备, start: 5.5, end: 7 },{ name: 首轮导弹发射, start: 7, end: 8.5 },{ name: 电子对抗…

Spark内核的设计原理

导读&#xff1a; 本期是DataFun深入浅出Apache Spark第一期的分享&#xff0c;主讲老师耿嘉安开场介绍了自己的从业经历&#xff0c;当前就职的数新网络与Spark相关的两款产品赛博数智引擎CyberEngine和赛博数据智能平台CyberData。 本次分享题目为《Spark内核的设计原理》&…

【测开能力提升-fastapi框架】fastapi能力提升 - 中间件与CORS

1. 中间件 1.1 介绍&#xff08;ChatGPT抄的&#xff0c;大致可以理解&#xff09; 一种机制&#xff0c;用于在处理请求和响应之前对其进行拦截、处理或修改。中间件可以在应用程序的请求处理管道中插入自定义逻辑&#xff0c;以实现一些通用的功能&#xff0c;如身份验证、…

系统架构设计师教程 第3章 信息系统基础知识-3.8 典型信息系统架构模型-解读

系统架构设计师教程 第3章 信息系统基础知识-3.8 典型信息系统架构模型-解读 3.8.1 政府信息化与电子政务3.8.1.1 电子政务的概念3.8.1.2 电子政务的内容3.8.1.2.1 政府与政府3.8.1.2.2 政府对企/事业单位3.8.1.2.3 政府对居民3.8.1.2.4 企业对政府3.8.1.2.5 居民对政府 3.8.1…