您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

Spring Cloud Hystrix 熔断器

时间:2023-08-12 17:13:14  来源:今日头条  作者:Java小玖

熔断器

熔断器模式源于Martin Fowler的Circuit Breaker一文。“熔断器”本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时,“熔断器”能够及时的切断故障电路,防止发生过载、发热、甚至起火等严重后果。

熔断器设计中有三种状态,生生世世,循环往复。

  1. closed(关闭状态,流量可以正常进入)
  2. open(即熔断状态,一旦错误达到阈值,熔断器将打开,拒绝所有流量)
  3. half-open(半开状态,open状态持续一段时间后将自动进入该状态,重新接收流量,一旦请求失败,重新进入open状态,但如果成功数量达到阈值,将进入closed状态)

整体流程见下图:

 

CLOSED关闭状态:允许流量通过。

OPEN打开状态:不允许流量通过,即处于降级状态,走降级逻辑。

HALF_OPEN半开状态:允许某些流量通过,并关注这些流量的结果,如果出现超时、异常等情况,将进入OPEN状态,如果成功,那么将进入CLOSED状态。

在分布式架构中,熔断器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。

限流

在开发高并发系统时,有很多手段保护系统,比如缓存降级限流。缓存的目的是提升系统访问速度和增大系统处理能力,可谓是抗高并发的银弹。而降级是当服务出问题或者影响到核心流程的性能,需要暂时屏蔽掉,待高峰过去或者问题解决后再打开的场景。而有些场景并不能用缓存和降级来解决,比如稀缺资源(秒杀、抢购)、写服务(如评论、下单)、频繁的复杂查询(评论的最后几页)等。因此,需要有一种手段来限制这些场景下的并发/请求量,这种手段就是限流。

限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的请求进行限速来保护系统,一旦达到限速速率则可以拒绝服务(定向到错误页或告知资源没有了)、排队或等待(比如秒杀、评论、下单)、降级(返回兜底数据或者默认数据,如商品详情页库存默认有货)。在压测时,我们能找出每个系统的处理峰值,然后通过设定峰值阈值,当系统过载时,通过拒绝过载的请求来保障系统可用。另外,也可以根据系统的吞吐量、响应时间、可用率来动态调整限流阈值。

一般开发高并发系统场景的限流有:限制总并发数(比如数据库连接池、线程池)、限制瞬时并发数(如Nginx的limit_conn模块,用来限制瞬间并发连接数)、限制时间窗口内的平均速率(如Guava的RateLimiter、Nginx的limit_req模块,用来限制每秒的平均速率),以及限制远程接口调用速率、限制MQ的消费速率等。另外还可以根据网络连接数、网络流量、CPU或内存负载等来限流。

限流算法

常见的限流算法有:令牌桶、漏桶。计数器也可以用来进行粗暴限流实现。

令牌桶算法

令牌桶算法,是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。令牌桶算法的描述如下:

  • 假设限制2r/s,则按照500毫秒的固定速率往桶内添加令牌。
  • 桶中最多存放b个令牌,当桶满时,新添加的令牌会被丢弃或拒绝。
  • 当一个n个字节大小的数据包到达,将从桶中删除n个令牌,接着数据包被发送到网络上。
  • 如果桶中的令牌不足n个,则不会删除令牌,且该数据包被限流(要么丢弃,要么在缓冲区等待)。

漏桶算法

漏桶作为计量工具时,可以用于流量整形和流量控制,漏桶算法的描述如下:

  • 一个固定容量的漏桶,按照常量固定速率流出水滴。
  • 如果桶是空的,则不需流出水滴。
  • 可以以任意速率流入水滴到漏桶。
  • 如果流入水滴超过了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。

常见的限流方式有:限制总并发数(数据库连接池、线程池)、限制瞬时并发数(如Nginx的limit_conn模块)、限制时间窗口的平均速率(如Guava的RateLimiter、Nginx的limit_req模块)、限制远程接口的调用速率、限制MQ的消费速率等。从应用的层面上来讲,又可以分为:接入层限流、应用层限流和分布式限流等。

Hystrix是什么

这一节方便阅读,我都抄下来来,具体看文档Hystrix:
https://Github.com.NETflix/Hystrix/wiki

在分布式环境中,许多服务依赖项中的一些不可避免地会失败。Hystrix是一个库,可通过添加延迟容错和容错逻辑来帮助您控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点,阻止它们之间的级联故障以及提供后备选项来实现这一目标,所有这些都可以提高系统的整体弹性。

Hystrix旨在执行以下操作:

  • 通过第三方客户端库访问(通常通过网络)依赖关系,以防止和控制延迟和故障。
  • 在复杂的分布式系统中停止级联故障。
  • 快速失败并迅速恢复。
  • 在可能的情况下,后退并优雅地降级。
  • 实现近实时监控,警报和操作控制。

复杂分布式体系结构中的应用程序有许多依赖项,每个依赖项在某些时候都不可避免地会失败。如果主机应用程序没有与这些外部故障隔离,那么它有可能被他们拖垮。

例如,对于一个依赖于30个服务的应用程序,每个服务都有99.99%的正常运行时间,你可以期望如下:

99.9930 = 99.7% 可用

也就是说一亿个请求的0.03% = 3000000 会失败

如果一切正常,那么每个月有2个小时服务是不可用的

现实通常是更糟糕


当一切正常时,请求看起来是这样的:

 

当其中有一个系统有延迟时,它可能阻塞整个用户请求:

 

在高流量的情况下,一个后端依赖项的延迟可能导致所有服务器上的所有资源在数秒内饱和(PS:意味着后续再有请求将无法立即提供服务)

 

当您使用Hystrix来包装每个底层依赖项时,上图中显示的体系结构将更改为类似于下图。每个依赖项彼此隔离,在发生延迟时可以饱和的资源受到限制,并且在回退逻辑中涵盖,该逻辑决定了在依赖项中发生任何类型的故障时要做出的响应:

 

Feign调用使用Hystrix示例

首先,前几节的环境,都有啊,没有或需要的去看我前几篇文章吧

pom.xml

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

feign调用接口

@FeignClient(name = "trade-promotion", fallback = PromotionClientFallback.class)
public interface PromotionClient {
    @RequestMApping(value = "/Promotion/delete", method = RequestMethod.GET)
    String releasePromotion(@RequestParam int orderID);
}

fallback类

 

@Component
public class PromotionClientFallback implements PromotionClient {
    @Override
    public String releasePromotion(@RequestParam int orderID) {
        return "hello ,fallback !";
    }
}

 

调用

 

@RestController
@RequestMapping(value = "/promotion", method = RequestMethod.GET)
public class PromotionController {
    @Autowired
    PromotionClient promotionClient;

    @RequestMapping(value = "/delete")
    public String delete(@RequestParam int orderID) {
        return promotionClient.releasePromotion(orderID);
    }
}

 

配置文件

#hystrix
feign.hystrix.enabled=true

好啦,可以啦.说下,就是如果远程调用接口异常,会执行Fallback返回 "hello ,fallback !";

如果你想知道为什么失败,失败的原因

 

@Component
public class PromotionClientFallbackFactory implements FallbackFactory<PromotionClient> {
    @Override
    public PromotionClient create(Throwable cause) {
        return new PromotionClient() {
            @Override
            public String releasePromotion(int orderID) {
                return "fallback:orderid=" + orderID + ",message:" + cause.getMessage();
            }
        };
    }
}

 

@FeignClient(name = "trade-promotion", fallbackFactory = PromotionClientFallbackFactory.class)
public interface PromotionClient {
    @RequestMapping(value = "/Promotion/delete", method = RequestMethod.GET)
    String releasePromotion(@RequestParam int orderID);
}

这样也可以

 

  @HystrixCommand(fallbackMethod = "error")
    public String search(@RequestParam int id) {
        try {
            Thread.sleep(10000);
            return id + "";
        }
        catch (Exception ex)
        {
            return ex.getMessage();
        }

    }
    public String error(int id)
    {
        return  "error"+id;
    }

 

好啦,这样就ok啦.

Hystrix配置

 

#hystrix
feign.hystrix.enabled=true
#是否开启fallback功能,默认为true
hystrix.command.default.fallback.enabled=true
#开启hystrix请求超时机制 也可以设置成永久不超时
hystrix.command.default.execution.timeout.enabled=true
#设置调用者执行的超时时间(单位毫秒),默认:1000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
#此属性设置从调用线程允许HystrixCommand.getFallback()方法允许的最大并发请求数
#如果达到最大的并发量,则接下来的请求会被拒绝并且抛出异常.
#默认为10
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests = 500
#当HystrixCommand.run()使用SEMAPHORE的隔离策略时,设置最大的并发量
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests = 1000
#是否开启断路器功能,默认为true
hystrix.command.default.circuitBreaker.enabled=true
#该属性设置滚动窗口中将使断路器跳闸的最小请求数量
#如果此属性值为20,则在窗口时间内(如10s内),如果只收到19个请求且都失败了,则断路器也不会开启。
#默认值:20
hystrix.command.default.circuitBreaker.requestVolumeThreshold=200
#断路器跳闸后,在此值的时间的内,hystrix会拒绝新的请求,只有过了这个时间断路器才会打开闸门
#默认值:5000
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=60000
#设置失败百分比的阈值。如果失败比率超过这个值,则断路器跳闸并且进入fallback逻辑
#默认值:50 ,即50%
hystrix.command.default.circuitBreaker=50
#如果设置true,则强制使断路器进行关闭状态,此时会允许执行所有请求,无论是否失败的次数达到circuitBreaker.errorThresholdPercentage值
#默认值:false
hystrix.command.default.circuitBreaker.forceOpe=false
#如果设置true,则强制使断路器进行关闭状态,此时会允许执行所有请求,无论是否失败的次数达到circuitBreaker.errorThresholdPercentage值
#默认值:false
hystrix.command.default.circuitBreaker.forceClosed=false
#设置线程池的core size,这是最大的并发执行数量。默认10
hystrix.threadpool.default.coreSize=500
#最大队列长度。设置BlockingQueue的最大长度。默认-1。
#如果设置成-1,就会使用SynchronizeQueue。
#如果其他正整数就会使用LinkedBlockingQueue。
hystrix.threadpool.default.maxQueueSize=1000
#设置拒绝请求的临界值。只有maxQueueSize为-1时才有效。
#设置设个值的原因是maxQueueSize值运行时不能改变,我们可以通过修改这个变量动态修改允许排队的长度。默认5
hystrix.threadpool.default.queueSizeRejectionThreshold=1000
#设置统计滚动窗口的时间长度,默认值:10000
hystrix.command.default.metrics.rollingStats.timeInMilliseconds=10000
#设置统计滚动窗口的桶数量,
#注意:以下配置必须成立,否则会抛出异常。
#metrics.rollingStats.timeInMilliseconds % metrics.rollingStats.numBuckets == 0
#如:10000/10、10000/20是正确的配置,但是10000/7错误的
#在高并发的环境里,每个桶的时间长度建议大于100ms
#默认值:10
hystrix.command.default.metrics.rollingStats.numBuckets=10
#设置执行延迟是否被跟踪,并且被计算在失败百分比中。如果设置为false,则所有的统计数据返回-1
#默认值: true
hystrix.command.default.metrics.rollingPercentile.enabled=true
#此属性设置统计滚动百分比窗口的持续时间,默认值:60000
hystrix.command.default.metrics.rollingPercentile.timeInMilliseconds=60000
#设置统计滚动百分比窗口的桶数量
#注意:以下配置必须成立,否则会抛出异常。
#metrics.rollingPercentile.timeInMilliseconds % metrics.rollingPercentile.numBuckets == 0
#如: 60000/6、60000/60是正确的配置,但是10000/7错误的
#在高并发的环境里,每个桶的时间长度建议大于1000ms
#默认值:6
hystrix.command.default.metrics.rollingPercentile.numBuckets=6
#此属性设置每个桶保存的执行时间的最大值。如果桶数量是100,统计窗口为10s,如果这10s里有500次执行,只有最后100次执行会被统计到bucket里去
#默认值:100
hystrix.command.default.metrics.rollingPercentile.bucketSize=100
#采样时间间隔
hystrix.command.default.metrics.healthSnapshot.intervalInMilliseconds=500


Tags:Spring   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Spring Security:保障应用安全的利器
SpringSecurity作为一个功能强大的安全框架,为Java应用程序提供了全面的安全保障,包括认证、授权、防护和集成等方面。本文将介绍SpringSecurity在这些方面的特性和优势,以及它...【详细内容】
2024-02-27  Search: Spring  点击:(53)  评论:(0)  加入收藏
Spring Security权限控制框架使用指南
在常用的后台管理系统中,通常都会有访问权限控制的需求,用于限制不同人员对于接口的访问能力,如果用户不具备指定的权限,则不能访问某些接口。本文将用 waynboot-mall 项目举例...【详细内容】
2024-02-19  Search: Spring  点击:(39)  评论:(0)  加入收藏
详解基于SpringBoot的WebSocket应用开发
在现代Web应用中,实时交互和数据推送的需求日益增长。WebSocket协议作为一种全双工通信协议,允许服务端与客户端之间建立持久性的连接,实现实时、双向的数据传输,极大地提升了用...【详细内容】
2024-01-30  Search: Spring  点击:(10)  评论:(0)  加入收藏
Spring实现Kafka重试Topic,真的太香了
概述Kafka的强大功能之一是每个分区都有一个Consumer的偏移值。该偏移值是消费者将读取的下一条消息的值。可以自动或手动增加该值。如果我们由于错误而无法处理消息并想重...【详细内容】
2024-01-26  Search: Spring  点击:(84)  评论:(0)  加入收藏
SpringBoot如何实现缓存预热?
缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。那么问题来了,在 Spring Boot 项目启动之后,在什么时候?在哪里可以将数据加载到缓存系...【详细内容】
2024-01-19  Search: Spring  点击:(86)  评论:(0)  加入收藏
Spring Boot2.0深度实践 核心原理拆解+源码分析
Spring Boot2.0深度实践:核心原理拆解与源码分析一、引言Spring Boot是一个基于Java的轻量级框架,它简化了Spring应用程序的创建过程,使得开发者能够快速搭建一个可运行的应用...【详细内容】
2024-01-15  Search: Spring  点击:(93)  评论:(0)  加入收藏
SpringBoot3+Vue3 开发高并发秒杀抢购系统
开发高并发秒杀抢购系统:使用SpringBoot3+Vue3的实践之旅随着互联网技术的发展,电商行业对秒杀抢购系统的需求越来越高。为了满足这种高并发、高流量的场景,我们决定使用Spring...【详细内容】
2024-01-14  Search: Spring  点击:(90)  评论:(0)  加入收藏
Spring Boot 3.0是什么?
Spring Boot 3.0是一款基于Java的开源框架,用于简化Spring应用程序的构建和开发过程。与之前的版本相比,Spring Boot 3.0在多个方面进行了改进和增强,使其更加易用、高效和灵活...【详细内容】
2024-01-11  Search: Spring  点击:(132)  评论:(0)  加入收藏
GraalVM与Spring Boot 3.0:加速应用性能的完美融合
在2023年,SpringBoot3.0的发布标志着Spring框架对GraalVM的全面支持,这一支持是对Spring技术栈的重要补充。GraalVM是一个高性能的多语言虚拟机,它提供了Ahead-of-Time(AOT)编...【详细内容】
2024-01-11  Search: Spring  点击:(124)  评论:(0)  加入收藏
Spring Boot虚拟线程的性能还不如Webflux?
早上看到一篇关于Spring Boot虚拟线程和Webflux性能对比的文章,觉得还不错。内容较长,抓重点给大家介绍一下这篇文章的核心内容,方便大家快速阅读。测试场景作者采用了一个尽可...【详细内容】
2024-01-10  Search: Spring  点击:(115)  评论:(0)  加入收藏
▌简易百科推荐
Web Components实践:如何搭建一个框架无关的AI组件库
一、让人又爱又恨的Web ComponentsWeb Components是一种用于构建可重用的Web元素的技术。它允许开发者创建自定义的HTML元素,这些元素可以在不同的Web应用程序中重复使用,并且...【详细内容】
2024-04-03  京东云开发者    Tags:Web Components   点击:(8)  评论:(0)  加入收藏
Kubernetes 集群 CPU 使用率只有 13% :这下大家该知道如何省钱了
作者 | THE STACK译者 | 刘雅梦策划 | Tina根据 CAST AI 对 4000 个 Kubernetes 集群的分析,Kubernetes 集群通常只使用 13% 的 CPU 和平均 20% 的内存,这表明存在严重的过度...【详细内容】
2024-03-08  InfoQ    Tags:Kubernetes   点击:(12)  评论:(0)  加入收藏
Spring Security:保障应用安全的利器
SpringSecurity作为一个功能强大的安全框架,为Java应用程序提供了全面的安全保障,包括认证、授权、防护和集成等方面。本文将介绍SpringSecurity在这些方面的特性和优势,以及它...【详细内容】
2024-02-27  风舞凋零叶    Tags:Spring Security   点击:(53)  评论:(0)  加入收藏
五大跨平台桌面应用开发框架:Electron、Tauri、Flutter等
一、什么是跨平台桌面应用开发框架跨平台桌面应用开发框架是一种工具或框架,它允许开发者使用一种统一的代码库或语言来创建能够在多个操作系统上运行的桌面应用程序。传统上...【详细内容】
2024-02-26  贝格前端工场    Tags:框架   点击:(47)  评论:(0)  加入收藏
Spring Security权限控制框架使用指南
在常用的后台管理系统中,通常都会有访问权限控制的需求,用于限制不同人员对于接口的访问能力,如果用户不具备指定的权限,则不能访问某些接口。本文将用 waynboot-mall 项目举例...【详细内容】
2024-02-19  程序员wayn  微信公众号  Tags:Spring   点击:(39)  评论:(0)  加入收藏
开发者的Kubernetes懒人指南
你可以将本文作为开发者快速了解 Kubernetes 的指南。从基础知识到更高级的主题,如 Helm Chart,以及所有这些如何影响你作为开发者。译自Kubernetes for Lazy Developers。作...【详细内容】
2024-02-01  云云众生s  微信公众号  Tags:Kubernetes   点击:(50)  评论:(0)  加入收藏
链世界:一种简单而有效的人类行为Agent模型强化学习框架
强化学习是一种机器学习的方法,它通过让智能体(Agent)与环境交互,从而学习如何选择最优的行动来最大化累积的奖励。强化学习在许多领域都有广泛的应用,例如游戏、机器人、自动驾...【详细内容】
2024-01-30  大噬元兽  微信公众号  Tags:框架   点击:(67)  评论:(0)  加入收藏
Spring实现Kafka重试Topic,真的太香了
概述Kafka的强大功能之一是每个分区都有一个Consumer的偏移值。该偏移值是消费者将读取的下一条消息的值。可以自动或手动增加该值。如果我们由于错误而无法处理消息并想重...【详细内容】
2024-01-26  HELLO程序员  微信公众号  Tags:Spring   点击:(84)  评论:(0)  加入收藏
SpringBoot如何实现缓存预热?
缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。那么问题来了,在 Spring Boot 项目启动之后,在什么时候?在哪里可以将数据加载到缓存系...【详细内容】
2024-01-19   Java中文社群  微信公众号  Tags:SpringBoot   点击:(86)  评论:(0)  加入收藏
花 15 分钟把 Express.js 搞明白,全栈没有那么难
Express 是老牌的 Node.js 框架,以简单和轻量著称,几行代码就可以启动一个 HTTP 服务器。市面上主流的 Node.js 框架,如 Egg.js、Nest.js 等都与 Express 息息相关。Express 框...【详细内容】
2024-01-16  程序员成功  微信公众号  Tags:Express.js   点击:(86)  评论:(0)  加入收藏
站内最新
站内热门
站内头条