降级熔断:如何屏蔽非核心系统故障的影响?

news2024/11/18 17:44:37

目录

前言

一、熔断是什么?

二、服务降级

三、雪崩是如何发生的

四、hystrix使用

五、降级机制要如何做

总结


前言

在“双十一”的巨大流量中,商品促销过程中出现了几次短暂的服务不可用,这给部分用户造成了不好的使用体验。事后,你们进行了细致的复盘,追查出现故障的根本原因,你发现,原因主要可以归结为两大类。

第一类原因是由于依赖的资源或者服务不可用,最终导致整体服务宕机。举例来说,在你的电商系统中就可能由于数据库访问缓慢,导致整体服务不可用。

另一类原因是你们乐观地预估了可能到来的流量,当有超过系统承载能力的流量到来时,系统不堪重负,从而出现拒绝服务的情况。

那么,你要如何避免再次出现这两类问题呢?我建议你采取降级、熔断以及限流的方案。今天这节课,我主要讲一下解决第一类问题的思路:降级和熔断。

限流、熔断和降级都是系统容错的重要设计模式。


一、熔断是什么?

是在流量过大时(或下游服务出现问题时),可以自动断开与下游服务的交互,并可以通过自我诊断下游系统的错误是否已经修正,或上游流量是否减少至正常水平,来自我恢复。熔断更像是自动化补救手段,可能发生在服务无法支撑大量请求或服务发生其他故障时,对请求进行限制处理,同时还可尝试性的进行恢复。

二、服务降级

主要是针对非核心业务功能,而核心业务如果流程超过预估的峰值,就需要进行限流。降级一般考虑的是分布式系统的整体性,从源头上切断流量的来源。降级更像是预估手段,在预计流量峰值前提下,提前通过配置功能降低服务体验,或暂停次要功能,保证系统主要流程功能平稳响应。

三、雪崩是如何发生的

局部故障最终会导致全局故障,这种情况有一个专业的名词儿,叫做“雪崩”。那么,为什么会发生雪崩呢?我们知道,系统在运行的时候是需要消耗一些资源的,包括 CPU、内存等系统资源,也包括执行业务逻辑的时候,需要的线程资源。

举个例子,一般在业务执行的容器内,都会定义一些线程池来分配执行任务的线程,比如在Tomcat 这种 Web 容器的内部,定义了线程池来处理 HTTP 请求;RPC 框架也给 RPC 服务端初始化了线程池来处理 RPC 请求。

这些线程池中的线程资源是有限的,如果这些线程资源被耗尽,那么服务自然也就无法处理新的请求,服务提供方也就宕机了。比如,你的垂直电商系统有四个服务 聚合服务A、商品服务B、促销服务C、评论服务D,A调用 B,B 调用 C 和 D。其中,聚合服务A、商品服务B、促销服务C是系统的核心服务,论服务D 是非核心服务。

所以,一旦作为入口的 A 流量增加,你可能会考虑把 A、B 和 C 服务扩容,忽略 D。那么D 就有可能因为无法承担这么大的流量,导致请求处理缓慢,进一步会让 B 在调用 D 的时候,B 中的请求被阻塞,等待 D 返回响应结果。这样一来,B 服务中被占用的线程资源就不能释放。

久而久之,B 就会因为线程资源被占满,无法处理后续的请求。那么从 A 发往 B 的请求,就会被放入 B 服务线程池的队列中,然后 A 调用 B 响应时间变长,进而拖垮 A 服务。你看,仅仅因为非核心服务 D 的响应时间变长,就可以导致整体服务宕机,这就是我们经常遇到的一种服务雪崩情况。

那么我们要如何避免出现上面这种情况呢?从我刚刚的介绍中你可以看到,因为服务调用方等待服务提供方的响应时间过长,它的资源被耗尽,才引发了级联反应,发生雪崩。所以在分布式环境下,系统最怕的反而不是某一个服务或者组件宕机,而是最怕它响应缓慢,因为,某一个服务或者组件宕机也许只会影响系统的部分功能,但它响应一慢,就会出现雪崩拖垮整个系统。

而我们在部门内部讨论方案的时候,会格外注意这个问题,解决的思路就是在检测到某一个服务的响应时间出现异常时,切断调用它的服务与它之间的联系,让服务的调用快速返回失败,从而释放这次请求持有的资源。这个思路也就是我们经常提到的降级和熔断机制。那么降级和熔断分别是怎么做的呢?它们之间有什么相同点和不同点呢?你在自己的项目中要如何实现熔断降级呢?

四、Hystrix简介

        Spring Cloud Hystrix是一款优秀的服务容错和保护组件,也是Spring Cloud的重要组件之一。

    Spring Cloud Hystrix是基于Netfilx公司的开源组件Hystrix实现的。提供熔断器功能,能够有效阻止分布式服务系统中出现联动故障,以提高微服务系统的弹性。Spring Cloud Hystrix具有服务降级,服务熔断,线程隔离,请求缓存,请求合并以及实时故障监控等强大功能。

Hystrix能做什么

  • 保护线程资源:防止单个服务的故障耗尽系统中所有的线程资源。
  • 快速失败机制:当某个服务发生了故障,不让服务调用方一直等待,而直接返回一个可预期的,可处理的降级响应。
  • 提供降级(FallBack)方案:在请求失败后,提供一个设计好的降级方案,当请求失败后调用此方法。
  • 防止故障扩散:使用熔断机制,防止故障扩散到其他服务。
  • 提供熔断器故障监控组件Hystrix Dashboard,随时监控熔断器的状态。
     

Hystrix服务熔断 

熔断机制是为了应对雪崩效应而出现一种微服务链路保护机制。

当微服务系统的某个微服务不可用或响应时间太长时,为了保护系统的服务整体可用性,熔断器会暂时切断对该服务的请求调用,并快速返回一个友好的错误响应信息。这种熔断状态不是永久的,在经历了一定时间后,熔断器会再次检测该微服务是否恢复正常,若恢复正常则恢复调用链路。

  • 熔断关闭状态(Closed):当服务访问正常时,熔断器处于关闭状态,服务调用方可以正常地对服务进行调用。
  • 熔断开启状态(Open):默认情况下,在固定时间内接口调用出错比率达到一个阈值(例如 50%),熔断器会进入熔断开启状态。进入熔断状态后,后续对该服务的调用都会被切断,熔断器会执行本地的降级(FallBack)方法。
  • 半熔断状态(Half-Open): 在熔断开启一段时间之后,熔断器会进入半熔断状态。在半熔断状态下,熔断器会尝试恢复服务调用方对服务的调用,允许部分请求调用该服务,并监控其调用成功率。如果成功率达到预期,则说明服务已恢复正常,熔断器进入关闭状态;如果成功率仍旧很低,则重新进入熔断开启状态。

Hystrix实现熔断机制

在SpringCloud中,熔断机制是通过Hystrix实现的。Hystrix会监控微服务间调用的情况,当失败调用达到一定比例时(例如5秒内失败20次),就会启动熔断机制。

  1. 当服务的调用出错率达到后超过Hystirx规定的出错比率(默认为50%),熔断器进入熔断开启状态。
  2. 熔断器进入熔断开启状态后,Hystrix会启动一个休眠时间窗,在这个时间窗内,该服务的降级逻辑会临时充当业务主逻辑,而原来的业务主逻辑不可用。
  3. 当有请求再次调用该服务时,会直接调用降级逻辑快递返回失败效应,以避免系统雪崩。
  4. 当休眠时间窗到期后,Hystrix会进入半熔断状态,允许部分请求对由原来的业务主逻辑进行调用,并监控其成功率。
  5. 如果调用成功率达到预期,说明服务恢复正常,Hystrix进入熔断关闭状态,服务原来的业务逻辑恢复。否则Hystrix将进入熔断开启状态,休眠时间窗口重新计时。

Hystrix熔断实现 

在pom.xml导入Hystrix依赖

         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.7.12</version>
        </dependency>
WebApplication 启动类 开启Hystrix
@EnableHystrix
@SpringBootApplication
public class WebApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
}

HystrixController 代码 

@EnableCircuitBreaker
@RestController
public class HystrixController {

    @HystrixCommand(fallbackMethod = "fallback", commandProperties =
            {

                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "100"),//指定多久超时,单位毫秒。超时进fallback
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//判断熔断的最少请求数,默认是10;只有在一个统计窗口内处理的请求数量达到这个阈值,才会进行熔断与否的判断
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "10"),//判断熔断的阈值,默认值50,表示在一个统计窗口内有50%的请求处理失败,会触发熔断
            })
    @RequestMapping("/test/{id}")
    public String test(@PathVariable("id") Integer id) throws Exception {
        Thread.sleep(1000);
        return "ok";
    }

    public String fallback(@PathVariable("id") Integer id) {
        return "fallback";
    }
}

启动测试

五、降级机制要如何做

除了熔断之外,我们在听业内分享的时候,听到最多的服务容错方式就是降级,那么降级又是怎么做的呢?它和熔断有什么关系呢?其实在我看来,相比熔断来说,降级是一个更大的概念。因为它是站在整体系统负载的角度上,放弃部分非核心功能或者服务,保证整体的可用性的方法,是一种有损的系统容错方式。这样看来,熔断也是降级的一种,除此之外还有限流降级、开关降级等等(限流降级我会在下一节课中提到,这节课主要讲一下开关降级)。

开关降级指的是在代码中预先埋设一些“开关”,用来控制服务调用的返回值。比方说,开关关闭的时候正常调用远程服务,开关打开时则执行降级的策略。这些开关的值可以存储在配置中心中,当系统出现问题需要降级时,只需要通过配置中心动态更改开关的值,就可以实现不重启服务快速地降级远程服务了。还是以电商系统为例,你的电商系统在商品详情页面除了展示商品数据以外,还需要展示评论的数据,但是主体还是商品数据,在必要时可以降级评论数据。所以,你可以定义这个开关为“degrade.comment”,写入到配置中心中,具体的代码也比较简单,就像下面这样:
 

 boolean switcherValue = getFromConfigCenter("degrade.comment"); // 从配置中心获取
 if (!switcherValue) { 
	List<Comment> comments = getCommentList(); // 开关关闭则获取评论数据
 } else {  
	List<Comment> comments = new ArrayList(); // 开关打开,则直接返回空评论数据
 }

当然了,我们在设计开关降级预案的时候,首先要区分哪些是核心服务,哪些是非核心服务。因为我们只能针对非核心服务来做降级处理,然后就可以针对具体的业务,制定不同的降级策略了。我给你列举一些常见场景下的降级策略,你在实际的工作中可以参考借鉴。针对读取数据的场景,我们一般采用的策略是直接返回降级数据。比如,如果数据库的压力比较大,我们在降级的时候,可以考虑只读取缓存的数据,而不再读取数据库中的数据;如果非核心接口出现问题,可以直接返回服务繁忙或者返回固定的降级数据。对于一些轮询查询数据的场景,比如每隔 30 秒轮询获取未读数,可以降低获取数据的频率(将获取频率下降到 10 分钟一次)。

而对于写数据的场景,一般会考虑把同步写转换成异步写,这样可以牺牲一些数据一致性和实效性来保证系统的可用性。

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

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

相关文章

编译运行windows+OpenMVG+OpenMVS+vs2017

安装vcpkg过程需要翻墙&#xff01;&#xff01;&#xff01; github下载代码 git clone https://github.com/microsoft/vcpkg git clone https://github.com/cdcseacave/VCG.git git clone https://github.com/cdcseacave/openMVS.git src安装vcpkg包 cd .\vcpkg .\bootstr…

电脑桌面可以设置半透明皮肤的待办事项软件推荐哪一款

无论你是在家工作还是在办公室&#xff0c;无论你是学生还是职场人士&#xff0c;每天都有许多任务等待着你。在这些琐事中&#xff0c;很容易遗漏一些重要的工作。那么&#xff0c;如何才能高效地记录和管理这些任务呢&#xff1f;生活和工作中的琐碎任务常常让我们感到忙碌而…

Hadoop、Hive安装

一、 工具 Linux系统&#xff1a;Centos&#xff0c;版本7.0及以上 JDK&#xff1a;jdk1.8 Hadoop&#xff1a;3.1.3 Hive&#xff1a;3.1.2 虚拟机&#xff1a;VMware mysql&#xff1a;5.7.11 工具下载地址: https://pan.baidu.com/s/1JYtUVf2aYl5–i7xO6LOAQ 提取码: xavd…

关于云主机root无法从VNC登录处理

一、问题描述 某次基线加固过程中&#xff0c;一线反馈离开工位后&#xff0c;返回时原root登录会话断开&#xff0c;使用普通用户无法切到root&#xff0c;尝试使用移动云控制台进行VNC登录&#xff0c;但也提示登录失败&#xff1a;报&#xff1a;incorrect auth 二、处理…

Nautilus Chain 联合香港数码港举办 BIG DEMO DAY活动,释放何信号?

在今年的 10 月 26 日 9:30-18:30 GMT8 期间&#xff0c;Nautilus Chain 联合香港数码港共同举办了 “BIG DEMO DAY” Web3 项目路演活动&#xff0c;包括Xwinner、Sleek、Tx、All weather、Coral Finance、DBOE、PARSIQ、Hookfi、Parallels、Fintestra 以及 dot.GAMING 等在内…

1763. 最长的美好子字符串

1763. 最长的美好子字符串 java代码&#xff1a; class Solution {public String longestNiceSubstring(String s) {int n s.length();int maxPos 0;int maxLen 0;for (int i 0; i < n; i) {int lower 0;int upper 0;for (int j i; j < n; j) {if (Character.isL…

(四)库存超卖案例实战——优化redis分布式锁

前言 在上一节内容中&#xff0c;我们已经实现了使用redis分布式锁解决商品“超卖”的问题&#xff0c;本节内容是对redis分布式锁的优化。在上一节的redis分布式锁中&#xff0c;我们的锁有俩个可以优化的问题。第一&#xff0c;锁需要实现可重入&#xff0c;同一个线程不用重…

Linux 应用程序CPU调度优化

缘起 实时操作系统&#xff08;Real-time operating system, RTOS&#xff09;&#xff0c;又称即时操作系统&#xff0c;它会按照排序运行、管理系统资源&#xff0c;并为开发应用程序提供一致的基础。实时操作系统与一般的操作系统相比&#xff0c;最大的特色就是实时性&…

如何通过员工工时管理降低企业成本?

作为当今快节奏商业环境的领导者或管理者&#xff0c;掌握员工的工作时间对于控制企业成本和确保每个人都各尽其责至关重要。 员工工时表软件就是这样一款工时跟踪管理解决方案&#xff1a;数字化的工时表有助于保护企业的财务不会被无节制的开支冲垮。然而&#xff0c;引入此…

windows PC virtualBox 配置

效果&#xff1a; oracle vitualbox 可以访问通PC主机&#xff0c;可以访问外网: 注意&#xff0c;如果docker0网络地址&#xff0c;和PC主机的网络地址冲突了&#xff0c;需要变更docker的网络地址&#xff1a; root/home/mysqlPcap/anti-tamper $ cat /etc/docker/daemon.js…

C++初阶1

目录 介绍&#xff1a; 一&#xff0c;命名空间 1-1&#xff0c;命名空间的定义 1-2&#xff0c;命名空间的使用 1-3&#xff0c;C标准官方命名空间 二&#xff0c;缺省参数 2.1&#xff0c;缺省参数分类 三&#xff0c;函数重载 四&#xff0c;引用 4-1&#xff0c;…

论文阅读——ELECTRA

论文下载&#xff1a;https://openreview.net/pdf?idr1xMH1BtvB 另一篇分析文章&#xff1a;ELECTRA 详解 - 知乎 一、概述 对BERT的token mask 做了改进。结合了GAN生成对抗模型的思路&#xff0c;但是和GAN不同。 不是对选择的token直接用mask替代&#xff0c;而是替换为…

中国两轮“技术派”绿源,为全球电动市场带来跨越式方案

历史越长的行业&#xff0c;遇到变革之时&#xff0c;需要经历的考验、做出的突破就越多。两轮电动车&#xff0c;这个非常本土化的赛道&#xff0c;就是如此。 中国是两轮电动车产销大国&#xff0c;自上世纪晚期开始&#xff0c;中国两轮电动车迅速发展&#xff0c;绿源等一…

【Linux】虚拟机部署与发布J2EE项目(Windows版本)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《微信小程序开发实战》。&#x1f3af;&#x1f3a…

优思学院|精益管理的八步法

精益管理是什么&#xff1f;所谓的精&#xff0c;即少而精&#xff0c;不投入多余的生产要素&#xff0c;只是在适当的时间生产必要数量的市场急需产品&#xff08;或下道工序急需的产品&#xff09;&#xff1b;所谓的益&#xff0c;即所有经营活动都要有益有效&#xff0c;具…

【C语言】字符函数与字符串函数

简单不先于复杂&#xff0c;而是在复杂之后。 目录 0. 前言 1. 函数介绍 1.1 strlen 1.1.1 介绍 1.1.2 strlen 函数模拟实现 1.1.2.1 计数器方法 1.1.2.2 递归方法 1.1.2.3 指针 - 指针方法 1.2 strcpy 1.2.1 介绍 1.2.2 strcpy 函数模拟实现 1.3 strcat 1…

TSINGSEE青犀睡岗离岗检测算法——确保加油站安全运营

众所周知&#xff0c;加油站是一个需要24小时营业的场所&#xff0c;由于夜间加油人员较少&#xff0c;员工极易处于疲劳或者睡眠状态&#xff0c;为保障安全和效率&#xff0c;通过TSINGSEE青犀睡岗离岗检测算法在加油站场景中&#xff0c;可以及时发现工作人员的疲劳状况&…

Python---while循环中else的基本语法(是同级关系)

为什么需要在while循环中添加else结构 循环可以和else配合使用&#xff0c; else下方缩进的代码指的是当循环正常结束之后要执行的代码。 强调&#xff1a; 循环 正常结束&#xff0c;else之后要执行的代码。 非正常结束&#xff0c;其else中的代码是不会执行的。&#…

【软考系统架构设计师】2023年系统架构师冲刺模拟习题之《数据库系统》

在数据库章节中可能会考察以下内容&#xff1a; 文章目录 数据库完整性约束&#x1f31f;数据库模式&#x1f31f;&#x1f31f;ER模式&#x1f31f;关系代数&#x1f31f;&#x1f31f;并发控制&#x1f31f;数据仓库与数据挖掘&#x1f31f;&#x1f31f;反规范化技术&#x…

【卖断货攻略】抢先看:美国全品类30天爆量近2亿刀!

距离10月27日黑五大促正式上线不足6小时&#xff0c;你上车了吗&#xff1f; 看到TikTok美国市场近期的GMV走势图&#xff0c;就感觉这届黑五将不简单。 为助力跨境商家在这个关键节点做好最后准备&#xff0c;本期超店有数将从选品、营销两大角度为大家盘点现阶段TikTok Shop…