Sentinel之熔断降级

  除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积。Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。

熔断的基本认识:

  在大型分布式架构中,一个用户的请求,可能是这样

  如果这个时候一个服务出现异常

  • 服务提供者不可用(硬件故障、程序bug、网络故障、用户请求量较大)
  • 重试导致的流量过大
  • 服务调用者使用同步调用,产生大量的等待线程占用系统资源,一旦线程资源被耗尽,调用者提供的服务也会变成不可用状态

  就会导致请求堆集从而出现整个服务不可用的问题。用古话来讲就是:千里之堤毁于蚁穴

  在复杂的分布式架构的应用程序有很多的依赖,都会不可避免的出现服务故障等问题。高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。

引入熔断机制:

  在分布式架构中,有一种解决方法,就是熔断机制。也就是说当下游服务因为访问压力过大或者其他原因导致响应变慢的时候,上游服务为了保护自己以及系统整体的可用性,可以暂时切断对于下游服务的调用。熔断在生活中也随处可见,

  1. 比如“跳闸”,当电压超过负荷时,开关会自动跳闸。从而防止出现电路烧毁带来的火灾。
  2. 比如股票市场的熔断,对于股票设置一个熔断价格,当价格触发到熔断点之后,交易会被暂停一段时间。或者交易可以继续进行,但是报价会限制在一定的范围

  那生活中的这种场景,能不能应用在架构设计中呢?大家会发现,架构是基于人的架构,所以架构的设计都是基于人对于事务的基本认识来实施的。因此越往后面学习,越能够发现很多设计思想都来自于生活。

Sentinel熔断降级:

  Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断。那么怎么去判断资源是否处于稳定状态呢?

  1. 平均响应时间 (DEGRADE_GRADE_RT):当 1s 内持续进入 5 个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位),那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作 4900 ms,若需要变更此上限可以通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置。
  2. 异常比例 (DEGRADE_GRADE_EXCEPTION_RATIO):当资源的每秒请求量 >= 5,并且每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
  3. 异常数 (DEGRADE_GRADE_EXCEPTION_COUNT):当资源近 1 分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。

  针对这些规则,Sentinel中给出了响应的字段来设置:

  在实战之前我们再来回顾以下Sentinel限流中最重要的处理链:

public class DefaultSlotChainBuilder implements SlotChainBuilder {

    @Override
    public ProcessorSlotChain build() {
        ProcessorSlotChain chain = new DefaultProcessorSlotChain();
        chain.addLast(new NodeSelectorSlot());
        chain.addLast(new ClusterBuilderSlot());
        chain.addLast(new LogSlot());
        chain.addLast(new StatisticSlot());
        chain.addLast(new SystemSlot());
        chain.addLast(new AuthoritySlot());
        chain.addLast(new FlowSlot());
        chain.addLast(new DegradeSlot());

        return chain;
    }

}

  可以看到最后一个Slot,就是熔断降级部分,他与限流是可以并存的。

Sentinel集成Dubbo实现服务熔断:

  这个熔断是跟着Sentinel集成Dubbo实现限流部分改造,小伙伴们可以先去浏览一下上一篇博文。

1.加入pom依赖

<dependency>  <!--这里面就一个接口,可以直接写到本项目中-->
  <groupId>com.wuzz.demo</groupId>
  <artifactId>sentinel-dubbo-api</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
  <groupId>org.apache.dubbo</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.7.2</version>
</dependency>
<dependency>
  <groupId>org.apache.curator</groupId>
  <artifactId>curator-recipes</artifactId>
  <version>4.0.1</version>
</dependency>
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-dubbo-adapter</artifactId>
  <version>1.6.3</version>
</dependency>

2.实现类:

@Service//把当前服务发布成dubbo服务
public class SentinelServiceImpl implements SentinelService {

    @Override
    public String sayHello(String name) {
        try {
            Thread.sleep(500); //为演示平均响应时间,让他睡500毫秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("begin execute sayHello:" + name);
        return "Hello World:" + name + "->timer:" + LocalDateTime.now();
    }
}

3.添加Dubbo配置:

@Configuration
@DubboComponentScan("com.wuzz.demo")
public class DubboConfig {

    @Bean
    public ApplicationConfig applicationConfig(){
        ApplicationConfig applicationConfig=new ApplicationConfig();
        applicationConfig.setName("sentinel-dubbo");
        applicationConfig.setOwner("wuzz");
        return applicationConfig;
    }
    @Bean
    public RegistryConfig registryConfig(){
        RegistryConfig registryConfig=new RegistryConfig();
        registryConfig.setAddress("zookeeper://192.168.1.101:2181");
        return registryConfig;
    }
    @Bean
    public ProtocolConfig protocolConfig(){
        ProtocolConfig protocolConfig=new ProtocolConfig();
        protocolConfig.setName("dubbo");
        protocolConfig.setPort(20880);
        return protocolConfig;
    }
}

4.添加熔断拓展点:

public class DataSourceInitFunc implements InitFunc {
    @Override
    public void init() throws Exception {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule();
        //下面这个配置的意思是,当1s内持续进入5个请求,平均响应时间都超过count(10ms),
        // 那么在接下来的timewindow(10s)内,对
        //这个方法的调用都会自动熔断,抛出异常:degradeException.
        //指定被保护的资源
        rule.setResource("com.wuzz.demo.SentinelService");
        //降级模式, RT(平均响应时间)、异常比例(DEGRADE_GRADE_EXCEPTION_RATIO)/异常数量
        //1s内处理5个请求
        rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
        rule.setCount(100); //阈值 5个请求平均响应时间超过100ms  触发降级
        rule.setTimeWindow(10);//降级的时间单位, 单位为s
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }
}

  在resource/META-INF/services/com.alibaba.csp.sentinel.init.InitFunc中配置改类的全路径,这样的话sentinel在触发限流时会去调用这个initFunc来解析规则

com.wuzz.demo.DataSourceInitFunc

5.主启动类:

@SpringBootApplication
public class SentinelProviderDegradeApplication {
    public static void main(String[] args) throws IOException {
        initFlowRules();
        SpringApplication.run(SentinelProviderDegradeApplication.class, args);
        System.in.read();
    }

    //初始化规则
    private static void initFlowRules() {
        List<FlowRule> rules = new ArrayList<>(); //限流规则的集合
        FlowRule flowRule = new FlowRule();
        flowRule.setResource("com.wuzz.demo.SentinelService:sayHello(java.lang.String)");//资源(方法名称、接口)
        flowRule.setCount(1000);//限流阈值 qps=1000
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);//限流阈值类型(QPS 或并发线程数)
        //流量控制手段(直接拒绝、Warm Up、匀速排队)
        flowRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
        flowRule.setLimitApp("sentinel-web");//流控针对的调用来源,若为 default 则不区分调用来源
        rules.add(flowRule);
        FlowRuleManager.loadRules(rules);
    }
}

  其中qps尽量大一点,因为这里主要是想测试熔断,不然抛出来的异常就不是我们想要的了,可能被限流了。  

  然后启动服务端,客户端,用JMeter压测,会看到抛出异常:

  我们可以捕获这个异常进行降级处理。

原文地址:https://www.cnblogs.com/wuzhenzhao/p/11496627.html

时间: 2024-11-10 07:00:03

Sentinel之熔断降级的相关文章

微服务之间的通讯安全(六)-Sentinel入门之注解及熔断降级

1.Sentinel注解支持 在学习熔断降级之前,我们先来看一下Sentinel的注解支持,我们使用spring-cloud-starter-alibaba-sentinel依赖,无需额外配置即可使用@SentinelResource注解定义资源. @SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项.常用属性如下: value:资源名称,必需项(不能为空): blockHandler / blockHandlerClass: blockHandle

这个注解一次搞定限流与熔断降级:@SentinelResource

在之前的<使用Sentinel实现接口限流>一文中,我们仅依靠引入Spring Cloud Alibaba对Sentinel的整合封装spring-cloud-starter-alibaba-sentinel,就完成了对所有Spring MVC接口的限流控制.然而,在实际应用过程中,我们可能需要限流的层面不仅限于接口.可能对于某个方法的调用限流,对于某个外部资源的调用限流等都希望做到控制.呢么,这个时候我们就不得不手工定义需要限流的资源点,并配置相关的限流策略等内容了. 今天这篇我们就来一起学

spring cloud微服务快速教程之(九) Spring Cloud Alibaba--sentinel-限流、熔断降级

0.前言 sentinel的限流.降级功能强大,可以在控制面板中任意制定规则,然后推送到微服务中: 可以根据URL单独制定规则,也可以根据资源名批量制定规则: 需要注意的地方是:1.GITHUB文件在国外的亚马逊服务器已经彻底被墙,无法下载,只能想法找国内的分享,自求多福 2.控制面板制定的规则只保存在内存中,重启就会消失,需要配合其他方式实现持久化存储规则,这点在生产环境中需要注意 1.运行sentinel sentinel只是一个JAR包,下载下来后,直接命令运行该JAR就行,默认的端口是8

熔断降级(Polly)

熔断降级(Polly) https://www.cnblogs.com/qhbm/p/9224307.html 一. 什么是熔断降级 熔断就是"保险丝".当出现某些状况时,切断服务,从而防止应用程序不断地尝试执行可能会失败的操作给系统造成"雪崩",或者大量的超时等待导致系统卡死. 降级的目的是当某个服务提供者发生故障的时候,向调用方返回一个错误响应或者替代响应.举例子:调用联通接口服务器发送短信失败之后,改用移动短信服务器发送,如果移动短信服务器也失败,则改用电信短

SpringCloud(6)---熔断降级理解、Hystrix实战

SpringCloud(6)---熔断降级理解.Hystrix实战 一.概念 1.为什么需要熔断降级 (1)需求背景 它是系统负载过高,突发流量或者网络等各种异常情况介绍,常用的解决方案. 在一个分布式系统里,一个服务依赖多个服务,可能存在某个服务调用失败,比如超时.异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败. 比如:某微服务业务逻辑复杂,在高负载情况下出现超时情况. 内部条件:程序bug导致死循环.存在慢查询.程序逻辑不对导致耗尽内存 外部条件:黑客攻击.促销.第三方系

何为熔断降级

今日,恰逢大雪,宜宅,曹操和刘备无所事事,于茅庐之中,煮酒论起天下事. 曹操:现今,微服务遍地开花,一些名词或者概念纷纷出山,广传教义.你看,那“熔断降级”便是其中一个. 刘备:不对,“熔断”和“降级”,这是两个人.只不过他们经常一起去别人家串门,所以就把他们名字连在一起叫的. 曹操:嗯嗯,你说得对.他们也都有自己官方的宣传口号, 比如熔断,“我们提供过载保护.当某个服务故障或者异常发生时,若这个异常条件需要我们处理,我们会采取一些保护措施---直接熔断整个服务,而不是一直等到此服务超时,从而防

Zuul2.X网关实现服务熔断降级

版本: <properties> <spring-boot.version>2.1.9.RELEASE</spring-boot.version> <spring-cloud.version>Greenwich.SR4</spring-cloud.version> </properties> 所需依赖: <properties> <spring-cloud.version>Greenwich.SR4</s

聊聊微服务熔断降级Hystrix

在现在的微服务使用的过程中,经常会遇到依赖的服务不可用,那么如果依赖的服务不可用的话,会导致把自己的服务也会拖死,那么就产生了熔断,熔断顾名思义就是当服务处于不可用的时候采取半开关的状态,达到一定数量后就熔断器就打开.这就相当于家里边的保险丝,如果电压过高的话,保险丝就会断掉,起到保护电器的作用. 目前支持熔断,降级的就是Hystrix,当然还有resilience4j还有Sentinel.今天咱们以Hystrix为主吧.其他的大家可以自行研究. Hystrix主要实现三个功能,接下来咱们继续展

ASP.NET Core-HttpClientFactory + Polly 实现熔断降级【转】

本文主要介绍 HttpClientFactory 整合 Polly 的使用,实现对 Http 请求的超时.重试.熔断.降级等操作. HttpClientFactory 集成 Polly 创建 .NET Core API 项目(这里使用的是 .NET Core 2.2): 安装 Microsoft.Extensions.Http.Polly NuGet Package; 在 Startup.cs 的 ConfigureServices 方法中添加 HttpClient 相关代码: public v