除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积。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.</version>
</dependency>
<dependency>
  <groupId>org.apache.curator</groupId>
  <artifactId>curator-recipes</artifactId>
  <version>4.0.</version>
</dependency>
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-dubbo-adapter</artifactId>
  <version>1.6.</version>
</dependency>

2.实现类:

@Service//把当前服务发布成dubbo服务
public class SentinelServiceImpl implements SentinelService { @Override
public String sayHello(String name) {
try {
Thread.sleep(); //为演示平均响应时间,让他睡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();
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(); //阈值 5个请求平均响应时间超过100ms 触发降级
rule.setTimeWindow();//降级的时间单位, 单位为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();//限流阈值 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压测,会看到抛出异常:

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

Sentinel之熔断降级的更多相关文章

  1. Spring Cloud Alibaba(三)Sentinel之熔断降级

    本项目演示如何使用 Sentinel 完成 Spring Cloud 应用的熔断降级调用. Sentinel 是阿里巴巴开源的分布式系统的流量防卫组件,Sentinel 把流量作为切入点,从流量控制, ...

  2. Spring cloud微服务安全实战-6-9sentinel之熔断降级

    来讲一下降级规则 服务会互相调用,服务A会有一些服务之间的依赖. 假设服务D的响应时间变长了.A调用D就会卡住了. 熔断,某一个服务出现问题,会把服务拖死.如果A出现,会把依赖A的那些服务拖死. 主要 ...

  3. SpringCloud 中集成Sentinel+Feign实现服务熔断降级

    Sentine 1.背景 Sentinel 是阿里中间件团队开源的,面向分布式服务架构的轻量级高可用流量控制组件,主要以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度来帮助用户保护服务的稳 ...

  4. 轻量级熔断降级框架 alibaba sentinel 应用

    一.简介: wiki:https://github.com/alibaba/Sentinel/wiki 选择: ♥ 开源,成熟(功能完备.实际应用),活跃(功能维护及拓展) ♥ 更轻量:依赖资源少:a ...

  5. sentinel流量控制和熔断降级执行流程之源码分析

    前言: sentinel是阿里针对服务流量控制.熔断降级的框架,如何使用官方都有很详细的文档,下载它的源码包 里面对各大主流框都做了适配按理,本系列文章目的 主要通过源码分析sentinel流量控制和 ...

  6. Sentinel熔断降级

    sentinel流量控制 Sentinel流量控制&服务熔断降级介绍 流量控制介绍 在这里我用景区的例子解释一下 一个旅游景点日接待游客数量为8K,8K以后的游客就无法买票进去景区. 对应编程 ...

  7. Spring Cloud & Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(JMeter模拟测试)

    目录 一. Sentinel概念 1. 什么是Sentinel? 2. Sentinel功能特性 3. Sentinel VS Hystrix 二. Docker部署Sentinel Dashboar ...

  8. SpringCloud微服务实战——搭建企业级开发框架(十五):集成Sentinel高可用流量管理框架【熔断降级】

      Sentinel除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一.由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积.Sentinel ...

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

    在之前的<使用Sentinel实现接口限流>一文中,我们仅依靠引入Spring Cloud Alibaba对Sentinel的整合封装spring-cloud-starter-alibab ...

随机推荐

  1. if_else

    //if.......else if......else //object IF_ELSE {// def main(args:Array[String]){// var x=30// if (x== ...

  2. 【前端】CSS基础

    3种html中设置css的方法: head中style标签 head中link标签rel属性.href后跟css文件目录 在需要使用css样式的标签添加style属性 1.CSS选择器 #id值 .c ...

  3. [洛谷P2567] SCOI2010 幸运数字

    问题描述 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是&quo ...

  4. SonarQube规则之bug类型

    1.".equals()" should not be used to test the values of "Atomic" classes.bug 主要不要 ...

  5. vi set the tab width for python

    Put your desired settings in the ~/.vimrc file -- See below for some guidelines and best practices. ...

  6. CF1051F The Shortest Statement Dijkstra + 性质分析

    动态询问连通图任意两点间最短路,单次询问. 显然,肯定有一些巧妙地性质(不然你就发明了新的最短路算法了233)有一点很奇怪:边数最多只比点数多 $20$ 个,那么就可以将这个图看作是一个生成树,上面连 ...

  7. 多重背包的二进制优化——DP

    #include<cstdio> #include<cstring> #include<algorithm> #define LL long long using ...

  8. Leetcode 8. String to Integer (atoi)(模拟题,水)

    8. String to Integer (atoi) Medium Implement atoi which converts a string to an integer. The functio ...

  9. eclipse配置apache tomcat运行时访问路径不需要项目名称

    问题:tomcat运行项目默认是要带上项目名的,有时候不想要项目名来访问,如何解决呢? 方法: 1:双击打开tomcat 2:选择Modules,选择你要修改的项目 3:点击Edit,把path修改成 ...

  10. IDEA 创建spring boot 的Hello World 项目

    1.Open IDEA,choose "New-->Project" 2.Choose "Spring Initializr" 3. Choose jav ...