网站建设亇金手指排名十五,网络营销公司招聘,wordpress不能启动怎么解决方法,江苏建设行业证书编号查询网站【Spring Cloud Alibaba】008-Sentinel 文章目录【Spring Cloud Alibaba】008-Sentinel一、服务雪崩1、概述2、解决方案常见的容错机制二、Sentinel#xff1a;分布式系统的流量防卫兵1、**Sentinel** 概述简介特性Sentinel 的开源生态Sentinel 的历史2、Sentinel 基本概念资源…【Spring Cloud Alibaba】008-Sentinel 文章目录【Spring Cloud Alibaba】008-Sentinel一、服务雪崩1、概述2、解决方案常见的容错机制二、Sentinel分布式系统的流量防卫兵1、**Sentinel** 概述简介特性Sentinel 的开源生态Sentinel 的历史2、Sentinel 基本概念资源规则3、Sentinel 功能和设计理念流量控制流量控制设计理念4、熔断降级什么是熔断降级熔断降级设计理念系统自适应保护5、Sentinel 是如何工作的三、Sentinel 使用1、基本使用第一步引入依赖第二步编写代码第三步访问测试缺点2、SentinelResource 注解3、注解开发第一步引入依赖第二步添加 bean第三步编写代码第四步访问测试四、降级规则初体验1、熔断降级规则 (DegradeRule)熔断策略属性说明熔断器事件监听2、初体验*五、控制台部署1、启动控制台第一步获取 Sentinel 控制台第二步启动2、客户端接入控制台第一步引入依赖第二步配置启动参数第三步重启并访问资源第四步查看控制台六、整合 Spring Cloud Alibaba1、引入依赖2、修改 yaml 配置3、启动 sentinel 和 项目七、流控规则1、概述2、QPS第一步增加一个接口第二步配置流控规则第三步访问测试第四步配置异常处理方法第五步重启并访问测试2、并发线程数概述第一步修改代码重启项目第二步设置流控规则第三步访问测试八、统一异常处理 BlockException1、定义统一返回类2、定义统一异常处理类3、修改接口代码4、设置流控访问测试九、流控模式1、概述2、关联说明第一步创建接口第二步运行访问设置限流策略第三步访问测试3、链路第一步编写代码第二步修改 yaml 配置第三步运行访问设置限流策略第四步访问测试备注十、流控效果1、概述快速失败Warm Up激增流量/预热流控排队等待脉冲流量2、预热流控第一步创建接口第二步运行访问设置限流策略第三步访问测试3、排队等待第一步修改流控规则第二步有规律刷新网页第三步设置排队等待第四步再次有规则刷新网页十一、整合 OpenFeign 降级参考文章十二、热点规则热点参数限流1、概述2、演示第一步创建接口第二步新增热点规则第三步编辑热点规则高级选项第四步访问测试十三、系统规则系统保护规则、概述2、系统保护配置示例十四、规则持久化1、持久化配置的必要2、三种模式原始模式拉模式推模式生产环境常用3、基于 Nacos 配置中心控制台实现推送*第一步引入依赖第二步启动 Nacos 并创建配置文件第三步修改 yaml 配置文件十五、Gateway 整合 Sentinel一、服务雪崩
1、概述
因服务提供者的不可用导致服务调用者的不可用并将不可用逐渐放大的过程就叫服务雪崩效应。
在服务提供者不可用的时候会出现大量重试的情况用户重试、代码逻辑重试这些重试最终导致进一步加大请求
流量。所以归根结底导致雪崩效应的最根本原因是**大量请求线程同步等待造成的资源耗尽。**当服务调用者使用同步调
用时, 会产生大量的等待线程占用系统资源。一旦线程资源被耗尽服务调用者提供的服务也将处于不可用状态,于是服务
雪崩效应产生了。
2、解决方案 稳定性 恢复性 常见的容错机制 超时机制 在不做任何处理的情况下服务提供者不可用会导致消费者请求线程强制等待而造成系统资源耗尽。加入超时机制一旦超时就释放资源。由于释放资源速度较快一定程度上可以抑制资源耗尽的问题。 服务限流 限制流量直接拒绝部分请求。 线程隔离 用户的请求将不再直接访问服务而是通过线程池中的空闲线程来访问服务如果线程池已满则会进行降级 处理用户的请求不会被阻塞至少可以看到一个执行结果例如返回友好的提示信息而不是无休止的等待或者看 到系统崩溃。 信号隔离 信号隔离也可以用于限制并发访问防止阻塞扩散与线程隔离最大不同在于执行依赖代码的线程依然是请求线程该线程需要通过信号申请如果客户端是可信的且可以快速返回可以使用信号隔离替换线程隔离降低开销。信号量的大小可以动态调整线程池大小不可以。 服务熔断 远程服务不稳定或网络抖动时暂时关闭就叫服务熔断。就像日常生活中电路跳闸压力太大的时候自动关闭。实时监测应用如果发现在一定时间内失败次数/失败率达到一定阈值就“跳闸”断路器打开——此时请求直接返回而不去调用原本调用的逻辑。跳闸一段时间后例如10秒断路器会进入半开状态这是一个瞬间态此时允许一次请求调用该调的逻辑如果成功则断路器关闭应用正常调用如果调用依然不成功断路器继续回到打开状态过段时间再进入半开状态尝试——通过”跳闸“应用可以保护自己而且避免浪费资源而通过半开的设计可实现应用的“自我修复“。当依赖的服务有大量超时时在让新的请求去访问根本没有意义只会无畏的消耗现有资源。 服务降级 有服务熔断必然要有服务降级。所谓降级就是当某个服务熔断之后服务将不再被调用此时客户端可以自己准备一个本地的 fallback回退回调返回一个缺省值。 例如(备用接口/缓存/mock数据) 。这样做虽然服务水平下降但好歹可用比直接挂掉要强当然这也要看适合的业务场景。
二、Sentinel分布式系统的流量防卫兵
1、Sentinel 概述
简介
Sentinel 是面向分布式服务架构的高可用流量防护组件主要以流量为切入点从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。
源码地址https://github.com/alibaba/Sentinel
官方文档https://github.com/alibaba/Sentinel/wiki
Sentinel 的使用可以分为两个部分:
核心库Java 客户端不依赖任何框架/库能够运行于 Java 8 及以上的版本的运行时环境同时对 Dubbo / Spring Cloud 等框架也有较好的支持见 主流框架适配。控制台Dashboard控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等。
特性
丰富的应用场景Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景例如秒杀即突发流量控制在系统容量可以承受的范围、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。完备的实时监控Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据甚至 500 台以下规模的集群的汇总运行情况。广泛的开源生态Sentinel 提供开箱即用的与其它开源框架 / 库的整合模块例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。完善的 SPI 扩展点Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。 Sentinel 的开源生态 Sentinel 的历史 2012 年Sentinel 诞生主要功能为入口流量控制。 为流量而生 2013-2017 年Sentinel 在阿里巴巴集团内部迅速发展成为基础技术模块覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。 说白了就是主要用来控制流量的 2018 年Sentinel 开源并持续演进。 人是有强烈的表达欲的特别是大师只有自己知道了关于宝藏的秘密是不行的你不分享出去别人还以为你啥也不知道呢 另外开源也是逼迫内部进行架构、代码大整理的机会 2019 年Sentinel 朝着多语言扩展的方向不断探索推出 C 原生版本同时针对 Service Mesh 场景也推出了 Envoy 集群流量控制支持以解决 Service Mesh 架构下多语言限流的问题。 逐渐完善并走向成熟 2020 年推出 Sentinel Go 版本继续朝着云原生方向演进。
2、Sentinel 基本概念
资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容例如由应用程序提供的服务或由应用程序调用的其它应用提供的服务甚至可以是一段代码。在接下来的文档中我们都会用资源来描述代码块。
只要通过 Sentinel API 定义的代码就是资源能够被 Sentinel 保护起来。大部分情况下可以使用方法签名URL甚至服务名称作为资源名来标示资源。
规则
围绕资源的实时状态设定的规则可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。 是规则也是策略根据策略制定规则 3、Sentinel 功能和设计理念
流量控制
什么是流量控制
流量控制在网络传输中是一个常用的概念它用于调整网络包的发送数据。然而从系统稳定性角度考虑在处理请求的速度上也有非常多的讲究。任意时间到来的请求往往是随机不可控的而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器可以根据需要把随机的请求调整成合适的形状如下图所示 流量控制设计理念
流量控制有以下几个角度: 资源的调用关系例如资源的调用链路资源和资源之间的关系 运行指标例如 QPS、线程池、系统负载等 QPS每秒访问量。 **控制的效果**例如直接限流、冷启动、排队等。 效果也是策略进而形成规则 目标 策略 规则三步走
Sentinel 的设计理念是让您自由选择控制的角度并进行灵活组合从而达到想要的效果。 自由选择 灵活组合 动态调整 理想效果 4、熔断降级
什么是熔断降级
除了流量控制以外及时对调用链路中的不稳定因素进行熔断也是 Sentinel 的使命之一。由于调用关系的复杂性如果调用链路中的某个资源出现了不稳定可能会导致请求发生堆积进而导致级联错误。 **一个服务常常会调用别的模块可能是另外的一个远程服务、数据库或者第三方 API 等。**例如支付的时候可能需要远程调用银联提供的 API查询某个商品的价格可能需要进行数据库查询。然而这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况请求的响应时间变长那么调用服务的方法的响应时间也会变长线程会产生堆积最终可能耗尽业务自身的线程池服务本身也变得不可用。 流量控制 熔断降级 现代微服务架构都是分布式的由非常多的服务组成。不同服务之间相互调用组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定就可能会层层级联最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级暂时切断不稳定调用避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段通常在客户端调用端进行配置。 注意本文档针对 Sentinel 1.8.0 及以上版本。1.8.0 版本对熔断降级特性进行了全新的改进升级请使用最新版本以更好地利用熔断降级的能力。 Sentinel 和 Hystrix 的原则是一致的当检测到调用链路中某个资源出现不稳定的表现例如请求响应时间长或异常比例升高的时候则对这个资源的调用进行限制让请求快速失败避免影响到其它的资源而导致级联故障。
熔断降级设计理念
在限制的手段上Sentinel 和 Hystrix 采取了完全不一样的方法。
Hystrix 通过 线程池隔离 的方式来对依赖在 Sentinel 的概念中对应 资源进行了隔离。这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本过多的线程池导致线程数目过多还需要预先给各个资源做线程池大小的分配并且对于一些使用了 ThreadLocal 的场景来说会有问题如 Spring 事务。 Hystrix 线程隔离做到了资源之间的彻底隔离但增加了成本和副作用 Sentinel 对这个问题采取了两种手段 新的工具 吸收旧工具的优势 弥补旧工具的不足 通过并发线程数进行限制 和资源池隔离的方法不同Sentinel 通过限制资源并发线程的数量来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下例如响应时间变长对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。针对慢调用和异常对资源进行降级 除了对并发线程数进行控制以外Sentinel 还可以根据响应时间和异常等不稳定因素来快速对不稳定的调用进行熔断。当依赖的资源出现响应时间过长后所有对该资源的访问都会被直接拒绝直到过了指定的时间窗口之后才重新渐进式地恢复。
系统自适应保护
Sentinel 同时提供系统维度的自适应保护能力。防止雪崩是系统防护中重要的一环。当系统负载较高的时候如果还持续让请求进入可能会导致系统崩溃无法响应。在集群环境下网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候这个增加的流量就会导致这台机器也崩溃最后导致整个集群不可用。
针对这个情况Sentinel 提供了对应的保护机制让系统的入口流量和系统的负载达到一个平衡保证系统在能力范围之内处理最多的请求。
5、Sentinel 是如何工作的
Sentinel 的主要工作机制如下 对主流框架提供适配或者显示的 API来定义需要保护的资源并提供设施对资源进行实时统计和调用链路分析。 第一告诉需要保护什么我来提供对其实时分析和统计 根据预设的规则结合对资源的实时统计信息对流量进行控制。同时Sentinel 提供开放的接口方便您定义及改变规则。 第二根据您想要达到的效果确定策略并制定规则我来执行 Sentinel 提供实时的监控系统方便您快速了解目前系统的状态。 第三我可以提供系统运行的实时状态
三、Sentinel 使用
1、基本使用
第一步引入依赖
!-- 引入 Sentinel 依赖 --
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-core/artifactIdversion1.8.6/version
/dependency第二步编写代码
package com.zibo.sentinel.controller;import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import jakarta.annotation.PostConstruct;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
import java.util.List;/*** author zibo* date 2023/2/24 13:43*/
RestController
RequestMapping(/sentinel)
public class HelloController {private static final String RESOURCE_NAME hello;RequestMapping(/hello)public String hello() {Entry entry null;try {entry SphU.entry(RESOURCE_NAME);// 被保护的逻辑return hello sentinel;} catch (Exception e) {// 处理被流控的逻辑return 被流控了;} finally {if (entry ! null) {entry.exit();}}}PostConstructpublic void initFlowRules() {// 流控规则ListFlowRule rules new ArrayList();// 流控FlowRule flowRule new FlowRule();// 设置资源flowRule.setResource(RESOURCE_NAME);// 设置规则类型flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);// 设置阈值每秒一次flowRule.setCount(1);// 添加到规则列表rules.add(flowRule);// 加载规则FlowRuleManager.loadRules(rules);}}第三步访问测试 缺点
业务侵入性很强需要在 controller 中写入非业务代码配置不灵活若需要添加新的受保护资源需要手动添加 init 方法来添加流控规则。
2、SentinelResource 注解 https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81 注意注解方式埋点不支持 private 方法。 SentinelResource 用于定义资源并提供可选的异常处理和 fallback 配置项。 SentinelResource 注解包含以下属性 value资源名称必需项不能为空 entryTypeentry 类型可选项默认为 EntryType.OUT blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称可选项。blockHandler 函数访问范围需要是 public返回类型需要与原方法相匹配参数类型需要和原方法相匹配并且最后加一个额外的参数类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数则可以指定 blockHandlerClass 为对应的类的 Class 对象注意对应的函数必需为 static 函数否则无法解析。 fallback/fallbackClassfallback 函数名称可选项用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常除了exceptionsToIgnore里面排除掉的异常类型进行处理。fallback 函数签名和位置要求 返回值类型必须与原函数返回值类型一致 方法参数列表需要和原函数一致或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。 fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数则可以指定 fallbackClass 为对应的类的 Class 对象注意对应的函数必需为 static 函数否则无法解析。 defaultFallbacksince 1.6.0默认的 fallback 函数名称可选项通常用于通用的 fallback 逻辑即可以用于很多服务或方法。默认 fallback 函数可以针对所有类型的异常除了exceptionsToIgnore里面排除掉的异常类型进行处理。若同时配置了 fallback 和 defaultFallback则只有 fallback 会生效。defaultFallback 函数签名要求 返回值类型必须与原函数返回值类型一致 方法参数列表需要为空或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。 defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数则可以指定 fallbackClass 为对应的类的 Class 对象注意对应的函数必需为 static 函数否则无法解析。 exceptionsToIgnoresince 1.6.0用于指定哪些异常被排除掉不会计入异常统计中也不会进入 fallback 逻辑中而是会原样抛出。
1.8.0 版本开始defaultFallback 支持在类级别进行配置。 注1.6.0 之前的版本 fallback 函数只针对降级异常DegradeException进行处理不能针对业务异常进行处理。 特别地若 blockHandler 和 fallback 都进行了配置则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandler、fallback 和 defaultFallback则被限流降级时会将 BlockException 直接抛出若方法本身未定义 throws BlockException 则会被 JVM 包装一层 UndeclaredThrowableException。
3、注解开发
第一步引入依赖
!-- 引入 Sentinel 注解开发依赖 --
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-annotation-aspectj/artifactIdversion1.8.6/version
/dependency第二步添加 bean
Bean
public SentinelResourceAspect sentinelResourceAspect() {return new SentinelResourceAspect();
}第三步编写代码
package com.zibo.sentinel.controller;import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import jakarta.annotation.PostConstruct;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
import java.util.List;/*** author zibo* date 2023/2/24 13:43*/
RestController
RequestMapping(/sentinel)
public class HelloController {// 原函数// blockHandler指定限流处理方法// fallback指定异常熔断后的降级处理方法SentinelResource(value hello, blockHandler helloFallback, fallback exceptionHandler)RequestMapping(/hello)public String hello() {return Hello Sentinel;}// Fallback 函数函数签名与原函数一致或加一个 Throwable 类型的参数.public String helloFallback() {return 被限流了;}// Block 异常处理函数参数最后多一个 BlockException其余与原函数一致.public String exceptionHandler(BlockException ex) {ex.printStackTrace();return 异常处理;}PostConstructpublic void initFlowRules() {// 流控规则ListFlowRule rules new ArrayList();// 流控FlowRule flowRule new FlowRule();// 设置资源flowRule.setResource(hello);// 设置规则类型flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);// 设置阈值每秒一次flowRule.setCount(1);// 添加到规则列表rules.add(flowRule);// 加载规则FlowRuleManager.loadRules(rules);}}第四步访问测试 测试结果符合预期如非注解开发结果一致限流时打印的异常如下 com.alibaba.csp.sentinel.slots.block.flow.FlowException四、降级规则初体验 关注重点每种规则的使用场景。 1、熔断降级规则 (DegradeRule)
熔断策略
Sentinel 提供以下几种熔断策略 慢调用比例 (SLOW_REQUEST_RATIO)选择以慢调用比例作为阈值需要设置允许的慢调用 RT即最大的响应时间请求的响应时间大于该值则统计为慢调用。当单位统计时长statIntervalMs内请求数目大于设置的最小请求数目并且慢调用的比例大于阈值则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态HALF-OPEN 状态若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断若大于设置的慢调用 RT 则会再次被熔断。 一句话慢调用比例就是调用时间较长的调用次数所占总调用次数的比例 1.调用一个请求发送到服务器服务器给与响应一个响应就是一个调用。 2.RT响应时间指系统对请求作出响应的时间。 3.慢调用当调用的时间响应的实际时间设置的RT的时这个调用叫做慢调用。 4.慢调用比例在所以调用中慢调用占有实际的比例 慢调用次数 / 调用次数 5.比例阈值自己设定的 慢调用次数 / 调用次数比例阈值 统计时长时间的判断依据 最小请求数设置的调用最小请求数 异常比例 (ERROR_RATIO)当单位统计时长statIntervalMs内请求数目大于设置的最小请求数目并且异常的比例大于阈值则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态HALF-OPEN 状态若接下来的一个请求成功完成没有错误则结束熔断否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0]代表 0% - 100%。 探测恢复状态尝试恢复到熔断前的正常状态的状态。 异常数 (ERROR_COUNT)当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态HALF-OPEN 状态若接下来的一个请求成功完成没有错误则结束熔断否则会再次被熔断。
注意异常降级仅针对业务异常对 Sentinel 限流降级本身的异常BlockException不生效。为了统计异常比例或异常数需要通过 Tracer.trace(ex) 记录业务异常。
示例代码
Entry entry null;
try {entry SphU.entry(key, EntryType.IN, key);// Write your biz code here.// BIZ CODE
} catch (Throwable t) {if (!BlockException.isBlockException(t)) {Tracer.trace(t);}
} finally {if (entry ! null) {entry.exit();}
}开源整合模块如 Sentinel Dubbo Adapter, Sentinel Web Servlet Filter 或 SentinelResource 注解会自动统计业务异常无需手动调用。
属性说明
更多操作Field说明默认值resource资源名即规则的作用对象grade熔断策略支持慢调用比例/异常比例/异常数策略慢调用比例count慢调用比例模式下为慢调用临界 RT超出该值计为慢调用异常比例/异常数模式下为对应的阈值timeWindow熔断时长单位为 sminRequestAmount熔断触发的最小请求数请求数小于该值时即使异常比率超出阈值也不会熔断1.7.0 引入5statIntervalMs统计时长单位为 ms如 60*1000 代表分钟级1.8.0 引入1000 msslowRatioThreshold慢调用比例阈值仅慢调用比例模式有效1.8.0 引入
同一个资源可以同时有多个降级规则。
熔断器事件监听
Sentinel 支持注册自定义的事件监听器监听熔断器状态变换事件state change event。示例
EventObserverRegistry.getInstance().addStateChangeObserver(logging,(prevState, newState, rule, snapshotValue) - {if (newState State.OPEN) {// 变换至 OPEN state 时会携带触发时的值System.err.println(String.format(%s - OPEN at %d, snapshotValue%.2f, prevState.name(),TimeUtil.currentTimeMillis(), snapshotValue));} else {System.err.println(String.format(%s - %s at %d, prevState.name(), newState.name(),TimeUtil.currentTimeMillis()));}});慢调用比例熔断示例SlowRatioCircuitBreakerDemo
2、初体验* 问题待解决上来就直接熔断了不按照我的配置走 package com.zibo.sentinel.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import jakarta.annotation.PostConstruct;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
import java.util.List;/*** author zibo* date 2023/2/24 13:43*/
RestController
RequestMapping(/sentinel)
public class HelloController {// 原函数SentinelResource(value hello, fallback fallbackExceptionHandler)RequestMapping(/hello/{nickname})public String hello(PathVariable String nickname) {int a 1 / 0;return Hello Sentinel nickname;}// Fallback 函数函数签名与原函数一致或加一个 Throwable 类型的参数.public String fallbackExceptionHandler(String nickname, Throwable t) {t.printStackTrace();return 服务被熔断了不要调用 nickname;}/*** 降级规则*/PostConstructpublic void initDegradeRules() {// 降级规则ListDegradeRule rules new ArrayList();// 降级DegradeRule degradeRule new DegradeRule();// 设置资源degradeRule.setResource(hello);// 设置规则类型degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);// 设置阈值异常数degradeRule.setCount(3);// 触发熔断的最小请求数degradeRule.setMinRequestAmount(3);// 单位统计时长1分钟degradeRule.setStatIntervalMs(60 * 1000);// 上述条件综合说明1分钟内如果至少有3个请求且异常数为3则触发熔断降级// 设置时间窗口// 熔断后多少秒后进入半熔断状态探测恢复状态// 比如熔断10秒后进入半熔断状态此时如果请求成功则恢复正常如果失败则继续熔断degradeRule.setTimeWindow(10);// 添加到规则列表rules.add(degradeRule);// 加载规则DegradeRuleManager.loadRules(rules);}}五、控制台部署 官方文档https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0 1、启动控制台
第一步获取 Sentinel 控制台
您可以从 release 页面 下载最新版本的控制台 jar 包。
您也可以从最新版本的源码自行构建 Sentinel 控制台
下载 控制台 工程使用以下命令将代码打包成一个 fat jar: mvn clean package
第二步启动 注意启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。 使用如下命令启动控制台
java -Dserver.port8080 -Dcsp.sentinel.dashboard.serverlocalhost:8080 -Dproject.namesentinel-dashboard -jar sentinel-dashboard.jar其中 -Dserver.port8080 用于指定 Sentinel 控制台端口为 8080。
从 Sentinel 1.6.0 起Sentinel 控制台引入基本的登录功能默认用户名和密码都是 sentinel。可以参考 鉴权模块文档 配置用户名和密码。 注若您的应用为 Spring Boot 或 Spring Cloud 应用您可以通过 Spring 配置文件来指定配置详情请参考 Spring Cloud Alibaba Sentinel 文档。 # 启动控制台命令
java -Dserver.port8090 -jar sentinel-dashboard-1.8.5.jar用户可以通过如下参数进行配置
-Dsentinel.dashboard.auth.usernamesentinel 用于指定控制台的登录用户名为 sentinel-Dsentinel.dashboard.auth.password123456 用于指定控制台的登录密码为 123456如果省略这两个参数默认用户和密码均为 sentinel-Dserver.servlet.session.timeout7200 用于指定 Spring Boot 服务端 session 的过期时间如 7200 表示 7200 秒60m 表示 60 分钟默认为 30 分钟 访问http://localhost:8090/即可
2、客户端接入控制台
第一步引入依赖 如果整合 spring cloud alibaba 则使用其对应的版本 !-- 引入 Sentinel 控制台 --
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-transport-simple-http/artifactIdversion1.8.5/version
/dependency第二步配置启动参数
启动时加入 JVM 参数 -Dcsp.sentinel.dashboard.serverconsoleIp:port 指定控制台地址和端口。若启动多个应用则需要通过 -Dcsp.sentinel.api.portxxxx 指定客户端监控 API 的端口默认是 8719。
从 1.6.3 版本开始控制台支持网关流控规则管理。您需要在接入端添加 -Dcsp.sentinel.app.type1 启动参数以将您的服务标记为 API Gateway在接入控制台时您的服务会自动注册为网关类型然后您即可在控制台配置网关规则和 API 分组。
除了修改 JVM 参数也可以通过配置文件取得同样的效果。更详细的信息可以参考 启动配置项。 第三步重启并访问资源 我这里刷新了好几次 第四步查看控制台 六、整合 Spring Cloud Alibaba
1、引入依赖
!-- Spring Cloud Alibaba Sentinel --
dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId
/dependency2、修改 yaml 配置
spring:application:name: sentinel-democloud:sentinel:transport:dashboard: localhost:80903、启动 sentinel 和 项目 访问接口 七、流控规则
1、概述
流量控制flow control其原理是监控应用流量的 QPS 或并发线程数等指标当达到指定的阈值时对流量进行控制以避免被瞬时的流量高峰冲垮从而保障应用的高可用性。 FlowRule RT(响应时间) 1/0.2s 5
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XQORsZq1-1677563371863)(https://gudu2019.oss-cn-beijing.aliyuncs.com/mdimg/6-2%E3%80%81Sentinel%E6%8E%A7%E5%88%B6%E5%8F%B0%E8%A7%84%E5%88%99%E9%85%8D%E7%BD%AE%E8%AF%A6%E8%A7%A3.png)] 同一个资源可以创建多条限流规则。FlowSlot 会对该资源的所有限流规则依次遍历直到有规则触发限流或者所有规则遍历完毕。一条限流规则主要由下面几个因素组成我们可以组合这些元素来实现不同的限流效果。 参考文档https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6 Field说明默认值resource资源名资源名是限流规则的作用对象count限流阈值grade限流阈值类型QPS 模式1或并发线程数模式0QPS 模式limitApp流控针对的调用来源default代表不区分调用来源strategy调用关系限流策略直接、链路、关联根据资源本身直接controlBehavior流控效果直接拒绝/WarmUp/匀速排队等待不支持按调用关系限流直接拒绝clusterMode是否集群限流否
2、QPS QPSQuery Per Second每秒请求数就是说服务器在一秒的时间内处理了多少个请求。 第一步增加一个接口
package com.zibo.sentinel.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** author zibo* date 2023/2/26 12:29*/
RestController
public class HiController {RequestMapping(/hi)public String hi() {return hi;}}第二步配置流控规则 第三步访问测试 第四步配置异常处理方法
package com.zibo.sentinel.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** author zibo* date 2023/2/26 12:29*/
RestController
public class HiController {RequestMapping(/hi)SentinelResource(value hi, blockHandler blockExceptionHandler)public String hi() {return hi;}public String blockExceptionHandler(BlockException e) {e.printStackTrace();return 限流了;}}第五步重启并访问测试 需要重新设置流控规则因为存在内存中项目重启后就失效了后续可以将规则持久化 2、并发线程数
概述
并发数控制用于保护业务线程池不被慢调用耗尽。
Sentinel 并发控制不负责创建和管理线程池而是简单统计当前请求上下文的线程数目正在执行的调用数目如果超出阈值新的请求会被立即拒绝效果类似于信号量隔离。并发数控制通常在调用端进行配置。
第一步修改代码重启项目
package com.zibo.sentinel.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;/*** author zibo* date 2023/2/26 12:29*/
RestController
public class HiController {RequestMapping(/hi)SentinelResource(value hi, blockHandler blockExceptionHandler)public String hi() {return hi;}public String blockExceptionHandler(BlockException e) {e.printStackTrace();return 限流了;}RequestMapping(/hello)SentinelResource(value hello, blockHandler blockExceptionHandler)public String hello() {// 睡眠 5 秒模拟业务处理时间try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}return hello;}}第二步设置流控规则 第三步访问测试 使用两个浏览器或一个浏览器的正常模式 一个浏览器的无痕模式前后迅速访问该地址 八、统一异常处理 BlockException
1、定义统一返回类 简化版 package com.zibo.sentinel.domain;import lombok.Data;Data
public class R {/*** 返回码*/private Integer code;/*** 返回消息*/private String msg;/*** 私有化构造方法*/private R() {}/*** 失败** param msg 返回消息* return 统一返回结果类*/public static R error(Integer code, String msg) {R r new R();r.setCode(code);r.setMsg(msg);return r;}
}2、定义统一异常处理类
package com.zibo.sentinel.common;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.databind.ObjectMapper;
import com.zibo.sentinel.domain.R;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** author zibo* date 2023/2/26 13:13* slogan 真正的大师永远怀着一颗学徒的心。——易大师*/
Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {Overridepublic void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {R r null;if (e instanceof FlowException) {r R.error(100,接口限流了);} else if (e instanceof DegradeException) {r R.error(101,接口降级了);} else if (e instanceof ParamFlowException) {r R.error(102,热点参数限流了);} else if (e instanceof SystemBlockException) {r R.error(103,触发系统保护规则了);} else if(e instanceof AuthorityException) {r R.error(104,授权规则不通过);}// 返回 jsonhttpServletResponse.setStatus(500);httpServletResponse.setCharacterEncoding(UTF-8);httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);new ObjectMapper().writeValue(httpServletResponse.getWriter(), r);}
}3、修改接口代码
package com.zibo.sentinel.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.zibo.sentinel.common.MyBlockExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** author zibo* date 2023/2/26 12:29*/
RestController
public class HiController {RequestMapping(/hello)public String hello() {return hello;}}4、设置流控访问测试 九、流控模式
1、概述
基于调用关系的流量控制。调用关系包括调用方、被调用方一个方法可能会调用其它方法形成一个调用链路的层次关系。
直接资源调用达到设置的阈值后直接被流控抛出异常。关联当两个资源之间具有资源争抢或者依赖关系的时候这两个资源便具有了关联。据此关系进行限流。链路根据调用链路入口限流。 资源之间的调用链路这些资源通过调用关系相互之间构成一棵调用树。
2、关联
说明
我们创建两个接口一个是读取操作一个是写入操作用以模拟当需要写入操作的时候对读取进行过限流。
第一步创建接口
RequestMapping(/read)
public String read() {return read;
}RequestMapping(/write)
public String write() {return write;
}第二步运行访问设置限流策略 第三步访问测试 3、链路
第一步编写代码
服务
package com.zibo.sentinel.service;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.stereotype.Service;/*** author zibo* date 2023/2/26 16:12* slogan 真正的大师永远怀着一颗学徒的心。——易大师*/
Service
public class TestService {SentinelResource(myService)public String myService() {return test service;}}接口
package com.zibo.sentinel.controller;import com.zibo.sentinel.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
public class HiController {Autowiredprivate TestService testService;RequestMapping(/test1)public String read() {return test1 testService.myService();}RequestMapping(/test2)public String write() {return test2 testService.myService();}}第二步修改 yaml 配置
spring:application:name: sentinel-democloud:sentinel:transport:dashboard: localhost:8090web-context-unify: false # add this config第三步运行访问设置限流策略 第四步访问测试 备注
使用了 SentinelResource 注解就不会出发统一异常处理了
十、流控效果
1、概述
快速失败
RuleConstant.CONTROL_BEHAVIOR_DEFAULT方式是默认的流量控制方式当 QPS 超过任意规则的阈值后新的请求就会被立即拒绝拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下比如通过压测确定了系统的准确水位时。
Warm Up激增流量/预热流控
Warm UpRuleConstant.CONTROL_BEHAVIOR_WARM_UP方式即预热/冷启动方式。当系统长期处于低水位的情况下当流量突然增加时直接把系统拉升到高水位可能瞬间把系统压垮。通过冷启动让通过的流量缓慢增加在一定时间内逐渐增加到阈值上限给冷系统一个预热的时间避免冷系统被压垮。
冷加载因子: codeFactor 默认是 3即请求 QPS 从 threshold / 3 开始经预热时长逐渐升至设定的 QPS 阈值。
通常冷启动的过程系统允许通过的 QPS 曲线如下图所示 排队等待脉冲流量
匀速排队RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER方式会严格控制请求通过的间隔时间也即是让请求以均匀的速度通过对应的是漏桶算法。
该方式的作用如下图所示 这种方式主要用于处理间隔性突发的流量例如消息队列。想象一下这样的场景在某一秒有大量的请求到来而接下来的几秒则处于空闲状态我们希望系统能够在接下来的空闲期间逐渐处理这些请求而不是在第一秒直接拒绝多余的请求。 注意匀速排队模式暂时不支持 QPS 1000 的场景。 2、预热流控 前一小段时间限流后逐渐放开到阈值。 第一步创建接口
package com.zibo.sentinel.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** author zibo* date 2023/2/27 12:47* slogan 真正的大师永远怀着一颗学徒的心。——易大师*/
RestController
public class TestController {RequestMapping(/test)public String test() {return test;}}第二步运行访问设置限流策略 第三步访问测试 控制台监控效果 3、排队等待
第一步修改流控规则 第二步有规律刷新网页 快速刷新 5 次间隔一段时间再快速刷新 5 次 第三步设置排队等待 第四步再次有规则刷新网页 监控 备注这里使用手动快速刷新方式测试使用 JMeter 测试更精准
十一、整合 OpenFeign 降级
参考文章
分布式系统Sentinel整合Open-Feign限流
https://blog.csdn.net/weixin_46146718/article/details/119926035
sentinel和openfeign整合
https://blog.csdn.net/qq_36575363/article/details/122794262
十二、热点规则热点参数限流
1、概述
热点热点即经常访问的数据。
很多时候我们希望统计某个热点数据中访问频次最高的数据并对其访问进行限制。 热点参数限流会统计传入参数中的热点参数并根据配置的限流阈值与模式对包含热点参数的资源调用进行限流。热 点参数限流可以看做是一种特殊的流量控制仅对包含热点参数的资源调用生效。 注意
热点规则需要使用 SentinelResource(resourceName) 注解否则不生效。参数必须是 7 种基本数据类型才会生效。
单机阈值 针对所有参数的值进行设置的一个公共的阈值**
假设当前参数大部分的值都是热点流量单机阈值就是针对热点流量进行设置额外针对普通流量进行参数值流控假设当前参数大部分的值都是普通流量单机阈值就是针对普通流量进行设置额外针对热点流量进行参数值流控
2、演示
第一步创建接口
package com.zibo.sentinel.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** author zibo* date 2023/2/27 13:44* slogan 真正的大师永远怀着一颗学徒的心。——易大师*/
RestController
public class HotController {RequestMapping(/hot/{name})SentinelResource(value hot, blockHandler hotBlockHandler)public String hot(PathVariable String name) {return 正常访问热点 name;}public String hotBlockHandler(PathVariable String name, BlockException e) {e.printStackTrace();return 热点流控 name;}}第二步新增热点规则 第三步编辑热点规则高级选项 第四步访问测试 十三、系统规则系统保护规则
、概述
Sentinel 系统自适应限流从整体维度对应用入口流量进行控制结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标通过自适应的流控策略让系统的入口流量和系统的负载达到一个平衡让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。 **Load 自适应仅对 Linux/Unixlike 机器生效**系统的 load1 作为启发指标进行自适应系统保护。当系统 load1 超过设定的启发值且系统当前的并发线程数超过估算的系统容量时才会触发系统保护BBR 阶段。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。 参考文章https://www.cnblogs.com/gentlemanhai/p/8484839.html **CPU usage1.5.0 版本**当系统 CPU 使用率超过阈值即触发系统保护取值范围 0.01.0比较灵敏。 平均 RT当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护单位是毫秒。 并发线程数当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。 **入口 QPS**当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
2、系统保护配置示例 演示略 十四、规则持久化
1、持久化配置的必要
规则默认保存在内存中服务重启需要重新配置生产环境下无法接受因此要进行持久化配置
2、三种模式
原始模式
如果不做任何修改Dashboard 的推送规则方式是通过 API 将规则推送至客户端并直接更新到内存中 这种做法的好处是简单无依赖坏处是应用重启规则就会消失仅用于简单测试不能用于生产环境。
拉模式
pull 模式的数据源如本地文件、RDBMS 等一般是可写入的。使用时需要在客户端注册数据源将对应的读数据源注册至对应的 RuleManager将写数据源注册至 transport 的WritableDataSourceRegistry 中。从文件中拉过来这种模式需要阅读一定的源码在源码的基础上进行扩展。
推模式生产环境常用
**生产环境下一般更常用的是 push 模式的数据源。**对于 push 模式的数据源,如远程配置中心ZooKeeper, Nacos, Apollo等等推送的操作不应由 Sentinel 客户端进行而应该经控制台统一进行管理直接进行推送数据源仅负责获取配置中心推送的配置并更新到本地。因此推送规则正确做法应该是 配置中心控制/Sentinel 控制台 → 配置中心 →Sentinel 数据源 → Sentinel而不是经 Sentinel 数据源推送至配置中心。
3、基于 Nacos 配置中心控制台实现推送* 可能由于我使用的版本比较新这么配置无法获取到 Nacos 里面的配置。 参考文章https://blog.csdn.net/MrHaoo/article/details/124169653 第一步引入依赖
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId
/dependency第二步启动 Nacos 并创建配置文件 第三步修改 yaml 配置文件
spring:application:name: sentinel-democloud:sentinel:transport:dashboard: localhost:8090web-context-unify: falsedatasource:flow-rule:nacos:server-addr: localhost:8848username: nacospassword: nacosdataId: sentinel-demo-flow-rulegroupId: DEFAULT_GROUPdata-type: jsonrule-type: flow十五、Gateway 整合 Sentinel
Spring Cloud Gateway 整合 sentinel 实现流控熔断
https://blog.csdn.net/a745233700/article/details/122917160
spring cloud alibaba-gateway使用以及整合sentinel
https://blog.csdn.net/weixin_38612401/article/details/126174715