SpringCloud(四):Hystrix熔断器介绍【Greenwich 版】

2023-10-21 11:40

本文主要是介绍SpringCloud(四):Hystrix熔断器介绍【Greenwich 版】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
Hystrix的中文含义是 “豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,这与 Hystrix 本身的功能不谋而合,因此 Netflix 团队将该框架命名为 Hystrix,并使用了对应的卡通形象做作为 logo。

分布式系统中经常会出现某个基础服务不可用造成整个系统不可用的情况,这种现象被称为服务雪崩效应。为了应对服务雪崩,一种常见的做法是手动服务降级。而 Hystrix 的出现,给我们提供了另一种选择。

服务雪崩效应的定义

服务雪崩效应是一种因 服务提供者 的不可用导致 服务调用者 的不可用,并将不可用 逐渐放大 的过程。如果所示:
在这里插入图片描述
上图中,A 为服务提供者,B 为 A 的服务调用者,C 和 D 是 B 的服务调用者。当 A 的不可用,引起 B 的不可用,并将不可用逐渐放大 C 和 D 时,服务雪崩就形成了。

服务雪崩形成的原因

我把服务雪崩的参与者简化为 服务提供者 和 服务调用者,并将服务雪崩产生的过程分为以下三个阶段来分析形成的原因:

  1. 服务提供者不可用
  2. 重试加大流量
  3. 服务调用者不可用

在这里插入图片描述
服务雪崩的每个阶段都可能由不同的原因造成,比如造成 服务不可用 的原因有:

  • 硬件故障
  • 程序 Bug
  • 缓存击穿
  • 用户大量请求

硬件故障可能为硬件损坏造成的服务器主机宕机,网络硬件故障造成的服务提供者的不可访问。
缓存击穿一般发生在缓存应用重启,所有缓存被清空时,以及短时间内大量缓存失效时。大量的缓存不命中,使请求直击后端,造成服务提供者超负荷运行,引起服务不可用。
在秒杀和大促开始前,如果准备不充分,用户发起大量请求也会造成服务提供者的不可用。

而形成 重试加大流量 的原因有:

  • 用户重试
  • 代码逻辑重试

在服务提供者不可用后,用户由于忍受不了界面上长时间的等待,而不断刷新页面甚至提交表单。
服务调用端的会存在大量服务异常后的重试逻辑。这些重试都会进一步加大请求流量。
最后,服务调用者不可用 产生的主要原因是:

  • 同步等待造成的资源耗尽

当服务调用者使用 同步调用 时,会产生大量的等待线程占用系统资源。一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态,于是服务雪崩效应产生了。

服务雪崩的应对策略

针对造成服务雪崩的不同原因,可以使用不同的应对策略:

  • 流量控制
  • 改进缓存模式
  • 服务自动扩容
  • 服务调用者降级服务

流量控制 的具体措施包括:

  • 网关限流
  • 用户交互限流
  • 关闭重试

因为Nginx的高性能, 目前一线互联网公司大量采用Nginx+Lua的网关进行流量控制, 由此而来的OpenResty也越来越热门.

用户交互限流的具体措施有: 1. 采用加载动画,提高用户的忍耐等待时间. 2. 提交按钮添加强制等待时间机制.

改进缓存模式 的措施包括:

  • 缓存预加载
  • 同步改为异步刷新

服务自动扩容 的措施主要有:

  • AWS的auto scaling

服务调用者降级服务 的措施包括:

  • 资源隔离
  • 对依赖服务进行分类
  • 不可用服务的调用快速失败

资源隔离主要是对调用服务的线程池进行隔离.

我们根据具体业务,将依赖服务分为: 强依赖和弱依赖. 强依赖服务不可用会导致当前业务中止,而弱依赖服务的不可用不会导致当前业务的中止.

不可用服务的调用快速失败一般通过 超时机制, 熔断器 和熔断后的 降级方法 来实现.

使用Hystrix预防服务雪崩

Hystrix的设计原则包括:

  • 资源隔离
  • 熔断器
  • 命令模式

资源隔离
货船为了进行防止漏水和火灾的扩散,会将货仓分隔为多个, 如下图所示:
在这里插入图片描述
这种资源隔离减少风险的方式被称为:Bulkheads(舱壁隔离模式).
Hystrix将同样的模式运用到了服务调用者上,Hystrix的隔绝策略分为两种:线程隔离信号量隔离

线程隔离:Hystrix在用户请求和服务之间加入了线程池。Hystrix为每个依赖调用分配一个小的线程池。用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满调用将被立即拒绝,进行降级处理,用户的请求不会被阻塞,至少可以看到一个执行结果(例如返回友好的提示信息),而不是无休止的等待或者看到系统崩溃。
信号量隔离:每次调用线程,当前请求通过计数信号量进行限制,当信号大于了最大请求数时,进行限制,调用fallback接口快速返回。

官网对信号量隔离的描述建议
Generally the only time you should use semaphore isolation for HystrixCommands is when the call is so high volume (hundreds per second, per instance) that the overhead of separate threads is too high; this typically only applies to non-network calls.
理解下两点:

  • 隔离的细粒度太高,数百个实例需要隔离,此时用线程池做隔离开销过大
  • 通常这种都是非网络调用的情况下

一般来说,只有当调用负载非常高时(例如每个实例每秒调用数百次)才需要使用信号量隔离,因为这种场景下使用线程隔离开销会比较高。信号量隔离一般仅适用于非网络调用的隔离。Hystrix中默认并且推荐使用线程隔离。

二者的比较

隔离策略线程隔离信号量隔离
线程HystrixCommand将会在单独的线程上执行HystrixCommand将会在调用线程上执行
开销排队、调度、上下文开销等无线程切换,开销低
异步支持不支持
并发支持支持(最大线程池大小)支持(最大信号量上限)
是否支持超时支持,直接返回不支持,如果阻塞,只能通过调用协议(如:socket超时才能返回)
是否支持熔断支持,当线程池到达maxSize后,再请求会触发fallback接口进行熔断支持,当信号量达到maxConcurrentRequests后。再请求会触发fallback

熔断器模式
熔断器模式定义了熔断器开关相互转换的逻辑:
在这里插入图片描述
服务的健康状况 = 请求失败数 / 请求总数.
熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值比较决定的.

当熔断器开关关闭时, 请求被允许通过熔断器. 如果当前健康状况高于设定阈值, 开关继续保持关闭. 如果当前健康状况低于设定阈值, 开关则切换为打开状态,当熔断器开关打开时, 请求被禁止通过.

当熔断器开关处于打开状态, 经过一段时间后(默认5s), 熔断器会自动进入半开状态, 这时熔断器只允许一个请求通过. 当该请求调用成功时, 熔断器恢复到关闭状态. 若该请求失败, 熔断器继续保持打开状态, 接下来的请求被禁止通过.

熔断器的开关能保证服务调用者在调用异常服务时, 快速返回结果, 避免大量的同步等待. 并且熔断器能在一段时间后继续侦测请求执行结果, 提供恢复服务调用的可能.

命令模式
Hystrix有两个请求命令 HystrixCommandHystrixObservableCommand
其中HystrixCommand依赖调用方法是run,服务降级方法是getFallback
HystrixObservableCommand依赖调用方法是construct,服务降级方法是resumeWithFallback

HystrixCommand是发出一个请求,返回一个结果

  • execute() — 从依赖的服务返回一个单一的结果对象,同步阻塞式;
  • queue() — 返回一个Future对象,异步非阻塞式;

HystrixObservableCommand可以发出多个请求,返回一个结果

  • observe() — 返回Obervable对象,热执行
  • toObservable() — 返回Obervable对象,冷执行

热执行就是不管你事件有没有注册完(onCompleted(),onError,onNext这三个事件注册),就去执行我的业务方法即(HystrixObservableCommand实现类中的construct()方法)
冷执行就是,事件监听方法注册完成后,才执行业务方法

Hystrix的内部处理逻辑

在这里插入图片描述

  1. 构建Hystrix的Command对象, 调用执行方法.
  2. Hystrix检查当前服务的熔断器开关是否开启, 若开启, 则执行降级服务getFallback方法.
  3. 若熔断器开关关闭, 则Hystrix检查当前服务的线程池是否能接收新的请求, 若超过线程池已满, 则执行降级服务getFallback方法.
  4. 若线程池接受请求, 则Hystrix开始执行服务调用具体逻辑run方法.
  5. 若服务执行失败, 则执行降级服务getFallback方法, 并将执行结果上报Metrics更新服务健康状况.
  6. 若服务执行超时, 则执行降级服务getFallback方法, 并将执行结果上报Metrics更新服务健康状况.
  7. 若服务执行成功, 返回正常结果.
  8. 若服务降级方法getFallback执行成功, 则返回降级结果.
  9. 若服务降级方法getFallback执行失败, 则抛出异常.

参考

防雪崩利器:熔断器 Hystrix 的原理与使用

相关阅读

项目代码
SpringCloud 汇总【Greenwich 版】
SpringCloud(一):Eureka注册中心【Greenwich 版】
SpringCloud(二):Ribbon负载均衡【Greenwich 版】
SpringCloud(三):Feign声明式服务调用【Greenwich 版】
SpringCloud(四):Hystrix熔断器介绍【Greenwich 版】
SpringCloud(五):Hystrix的请求熔断与服务降级【Greenwich 版】
SpringCloud(六):Hystrix的请求合并【Greenwich 版】
SpringCloud(七):Hystrix仪表盘与Turbine集群监控【Greenwich 版】
SpringCloud(八):Zuul网关【Greenwich 版】
SpringCloud(九):Config配置中心【Greenwich 版】
SpringCloud(十):Bus消息总线【Greenwich 版】
SpringCloud(十一):Stream消息驱动 + RabbitMQ【Greenwich 版】
SpringCloud(十二):Sleuth链路跟踪【Greenwich 版】

这篇关于SpringCloud(四):Hystrix熔断器介绍【Greenwich 版】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/254161

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数