SpringCloud极简入门-熔断器Hystrix

简介: 在电影里面经常出现的场景,在冰山雪地不要大声呼喊,因为声音的震动会导致雪球的滑落,然后引起连锁反应导致整个雪山的崩塌这就是生活中的雪崩。在微服务里面也是一样,服务的调用非常复杂的 ,一个请求往往需要很多的微服务共同完成,可能会形成很长的服务调用链,在整个服务调用链中,某一个服务发生故障会导致调用它的服务跟着异常,然后导致整个调用链调用的异常,甚至导致整个微服务瘫痪 , — 这就是雪崩效应。

1.理解Hystrix

1.1.雪崩效应

在电影里面经常出现的场景,在冰山雪地不要大声呼喊,因为声音的震动会导致雪球的滑落,然后引起连锁反应导致整个雪山的崩塌这就是生活中的雪崩。在微服务里面也是一样,服务的调用非常复杂的 ,一个请求往往需要很多的微服务共同完成,可能会形成很长的服务调用链,在整个服务调用链中,某一个服务发生故障会导致调用它的服务跟着异常,然后导致整个调用链调用的异常,甚至导致整个微服务瘫痪 , — 这就是雪崩效应。如下图:

1.2.Hystrix介绍

Hystrix是国外知名的视频网站Netflix所开源的非常流行的高可用架构框架。Hystrix能够完美的解决分布式系统架构中打造高可用服务面临的一系列技术难题,如雪崩。

Hystrix是处理依赖隔离的框架,将出现故障的服务通过熔断、降级等手段隔离开来,这样不影响整个系统的主业务(比如你得了传染病是不是要把你关起来隔离呢),同时也是可以帮我们做服务的治理和监控。

Hystrix的英文是豪猪,中文翻译为 熔断器,其思想来源于我们家里的保险开关,当家里出现短路,保险开关及时切掉电路,保证家里人员的安全,其目的就是起保护作用。

其设计原则如下:

1.防止单个服务异常导致整个微服务故障。

2.快速失败,如果服务出现故障,服务的请求快速失败,线程不会等待。

3.服务降级,请求故障可以返回设定好的二手方案数据(兜底数据)。

4.熔断机制,防止故障的扩散,导致整个服务瘫痪。

5.服务监控,提供了Hystrix Bashboard仪表盘,实时监控熔断器状态

1.3.Hystrix的功能

资源隔离

资源隔离包括线程池隔离和信号量隔离,作用是限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用 ,这里可以简单的理解为资源隔离就是限制请求的数量。

就好比在肺炎疫情爆发期间,是不是要限制人口的流动量,流动量越大可能会导致更多的肺炎患者出现。

线程池隔离:使用一个线程池来存储当前请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求先入线程池队列。这种方式要为每个依赖服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)

信号量隔离:使用一个原子计数器(或信号量)记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃该类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)

线程池和信号量对比:

线程池 线程池 信号量
线程 与调用线程非相同线程 与调用线程相同(jetty线程)
开销 排队、调度、上下文开销等 无线程切换,开销低
异步 支持 不支持
并发支持 支持(最大线程池大小) 支持(最大信号量上限)
服务熔断

熔断机制是对服务链路的保护机制,如果链路上的某个服务不可访问,调用超时,发生异常等,服务会触发降级返回托底数据,然后熔断服务的调用(失败率达到某个阀值服务标记为短路状态),当检查到该节点能正常使用时服务会快速恢复。

简单理解就是当服务不可访问了或者服务器报错了或者服务调用超过一定时间没返回结果,就立马触发熔断机制配合降级返回预先准备的兜底数据返回,不至于长时间的等待服务的相应造成大量的请求阻塞,也不至于返回一些错误信息给客户端,而是返回一些兜底数据。

降级机制

超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。

简单理解就是服务降级就是当服务因为网络故障,服务器故障,读取超时等原因造成服务不可达的情况下返回一些预先准备好的数据给客户端。

在生活中服务降级到处可见,如在系统故障我们会返回友好的提示“服务暂时不可用”,或者如淘宝双11期间退款服务,留言服务暂时不可用,这个就是为了保证正常的购物流程相关服务没问题,然后人为的关闭一些不重要的服务,配合降级返回一些托底数据返回给用户(比如返回友好的提示信息“暂时不能退款”)。

缓存

提供了请求缓存、请求合并实现 , 在高并发的场景之下,Hystrix请求缓存可以方便地开启和使用请求缓存来优化系统,达到减轻高并发时请求线程的消耗、降低请求响应时间的效果。

1.4.Hystrix工作机制

正常情况下,断路器处于关闭状态(Closed),如果调用持续出错或者超时达到设定阈值,电路被打开进入熔断状态(Open),这时请求这个服务会触发快速失败(立马返回兜底数据不要让线程死等),后续一段时间内的所有调用都会被拒绝(Fail Fast),一段时间以后(withCircuitBreakerSleepWindowInMilliseconds=5s),保护器会尝试进入半熔断状态(Half-Open),允许少量请求进来尝试,如果调用仍然失败,则回到熔断状态,如果调用成功,则回到电路闭合状态;

就如同你生病了,你需要去医院看病,你的状态被标记为为“生病状态”(短路) ,你的朋友来找你玩,可能你的女朋友需要去回绝你的朋友说你生病了(托底,返回一些友好提示) , 当你的病好了,你的朋友又可以找你玩了(服务正常)。

2.Hystrix编码实战

查考文档:https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/multi/multi__circuit_breaker_hystrix_clients.html#_how_to_include_hystrix

在springcloud-order-server-1030工程的基础身上做修改,我们让Hystrix和Ribbon配合使用,下一章节我们讲Feign和Hystirx配合使用。

2.1.导入依赖

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

2.2.配置类开启Hystrix

主配置类通过 @EnableCircuitBreaker 标签开启熔断功能

/*** 订单的启动类*/@SpringBootApplication@EnableEurekaClient@EnableCircuitBreaker//开启Hystrix熔断publicclassOrderServerApplication1030{
//省略...

2.3.方法熔断

通过 @HystrixCommand 标签标记方法熔断,标签的fallbackMethod属性指定拖地方法。那么当该方法在像远程服务发起调用出现异常,或是方法本身出现异常都会触发托底方法的执行,最终结果是托底方法的返回结果。

//浏览器调用该方法@HystrixCommand(fallbackMethod="fallbackMethod")   //方法熔断@RequestMapping(value="/order/{id}",method=RequestMethod.GET)
publicUsergetById(@PathVariable("id")Longid){
//发送http请求调用 user的服务,获取user对象 : RestTemplate//user的ip,user的端口,user的Controller路径//String url = "http://localhost:1020/user/"+id;Stringurl="http://user-server/user/"+id;
//发送http请求returnrestTemplate.getForObject(url, User.class);
}
//降级方法 , 参数和返回值必须和被熔断的方法一致 ,方法名要和  fallbackMethod 的值一致publicUserfallbackMethod(@PathVariable("id")Longid){
//返回托底数据returnnewUser(-1L ,"无此用户","用户服务不可用");
}

我们可以在每个方法上打@HystrixCommand(fallbackMethod = “fallbackMethod”) 标签进行方法单独熔断,也可以在Controller使用 @DefaultProperties做统一配置,如

@RestController@DefaultProperties(defaultFallback="fallbackMethod")   //统一降级配置publicclassOrderController {
@HystrixCommand//方法熔断@RequestMapping(value="/order/{id}",method=RequestMethod.GET)
publicUsergetById(@PathVariable("id")Longid)
//...省略...

2.4.托底方法

//托底方法publicUserfallbackMethod(){
//返回友好的提示信息returnnewUser(-1L,"无此用户","用户服务不可用");
}

注意:公共的托底方法不应该有参数。返回类型必须和熔断的方法的返回类型兼容,比如这里可以返回User或者User的子类。

在生产环境中我们可以让所有的方法都有相同的返回结果,如统一的JSON返回结果(JSONResult) ,那么在默认的降级方法中的返回类型就可以使用JSONResult了。

2.4.测试熔断

依次启动:springcloud-eureka-server-1010 , springcloud-user-server-1020 , springcloud-order-server-1030

浏览器访问 http://localhost:1030/order/1 ,当用户服务 springcloud-user-server-1020 正常启动的时候,订单服务是可以访问,浏览器也可以收到结果 , 当关闭掉用户服务 ,订单服务会触发熔断,返回托底数据

3.Hystrix参数配置

3.1.熔断参数配置

Hystrix提供了如下的几个关键参数(com.netflix.hystrix.HystrixCommandProperties),来对一个熔断器进行配置:

  • hystrix.command.default.circuitBreaker.requestVolumeThreshold 滑动窗口的大小,默认为20
  • hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds 过多长时间熔断器再次检测是否开启默认5000(5s)
  • hystrix.command.default.circuitBreaker.errorThresholdPercentage 错误率,默认50%

3个参数放在一起,所表达的意思就是:

每当20个请求中,有50%失败时,熔断器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。直到5s钟之后,重新检测该触发条件,判断是否把熔断器关闭,或者继续打开。

hystrix:   command:    default:      circuitBreaker:        requestVolumeThreshold: 20 #20个请求中        errorThresholdPercentage: 50 #出错百分比阈值        sleepWindowInMilliseconds: 50000 #短路5秒钟,尝试恢复

3.2.超时设置

我们知道在服务的远程调用过程中,如果调用时间过久会触发Ribbon的超时,Hystrix也有超时配置 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds

我们往往会把Ribbon和Hystrix的超时配合起来配置:

ribbon:  MaxAutoRetries: 1 #最大重试次数  MaxAutoRetriesNextServer: 1 #切换实例的重试次数  OkToRetryOnAllOperations: false # 对所有的操作请求都进行重试,  ConnectTimeout: 1000 #请求连接的超时时间  ReadTimeout: 1800 #请求处理的超时时间hystrix:  command:    default:      execution:        isolation:          thread:            timeoutInMilliseconds: 3000 #hystrix超时,置thread和semaphore两种隔离策略的超时时间

需要注意的是,我们设置了重试机制就需要Hystrix超时时间大于Ribbon超时时间,因为Hystrix超时后会直接熔断就不会再出发重试

hystrix超时=(1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout

如果要针对于某个API做单独的超时设置也可以通过如下方式单独指定

@HystrixCommand(commandProperties= {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="3000")
})
@RequestMapping(value="/order/{id}",method=RequestMethod.GET)
publicUsergetById(@PathVariable("id")Longid){
...

3.3.资源隔离模式

在Hystrix可以通过execution.isolation.strategy配置切换资源隔离模式:线程池或者信号量

hystrix:  command:    default:      execution:        isolation:          strategy: THREAD #默认是线程池,可以修改为信号量: SEMAPHORE

除了上面方式也可以使用如下方式单独指定:

@HystrixCommand(fallbackMethod="", commandProperties=@HystrixProperty(name="execution.isolation.strategy", value="THREAD") )
@RequestMapping(value="/order/{id}",method=RequestMethod.GET)
publicUsergetById(@PathVariable("id")Longid){
...

3.4.最大请求设置

通过 execution.isolation.semaphore.maxConcurrentRequests 配置信号量模式下的最大请求数量(并发)

hystrix:  command:    default:      execution:        isolation:          thread:            timeoutInMilliseconds: 30000   #hystrix超时          strategy: SEMAPHORE #默认是线程池,可以修改为信号量: SEMAPHORE          semaphore:            maxConcurrentRequests: 10 # SEMAPHORE模式下 , 1秒钟最大请求数量,默认10

在线程池模式下通过 hystrix.threadpool.default.coreSize设置线程并发数量,

通过hystrix.threadpool.default.maxQueueSize 设置线程池队列模式,通过    hystrix.threadpool.default.queueSizeRejectionThreshold设置排队数量 ,见:com.netflix.hystrix.HystrixThreadPoolProperties

hystrix:  threadpool:    default:      coreSize: 10 #最大线程数 , 并发执行的最大线程数,默认10      maxQueueSize: -1 #最大排队长度。默认-1,使用SynchronousQueue。其他值则使用 LinkedBlockingQueue。      queueSizeRejectionThreshold: 5      ...

3.5.Fallback设置

并发达到 hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests 配置的值时,fallback会被被调用,模式10

通过配置hystrix.command.default.fallback.enabled 开启fallback ,即请求失败尝试走托底

hystrix:  command:    default:      fallback:         enabled: true #请求失败时是否要走托底         isolation:           semaphore:             maxConcurrentRequests: 10 #fallback最大并发数量
目录
相关文章
|
2月前
springCloud之服务降级熔断Hystrix、OpenFeign
springCloud之服务降级熔断Hystrix、OpenFeign
81 0
|
2天前
|
缓存 监控 负载均衡
一文讲明Hystrix熔断器
这篇文章详细阐述了Hystrix熔断器的原理和应用,解释了分布式系统中服务雪崩的问题,并展示了如何在Spring Cloud框架中使用Hystrix进行熔断和降级处理。
一文讲明Hystrix熔断器
|
16天前
|
负载均衡 监控 Java
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
|
1月前
|
监控 Java 开发者
Spring Cloud中的服务熔断与降级
Spring Cloud中的服务熔断与降级
|
2月前
|
监控 Java 微服务
Spring Cloud 之 Hystrix
Spring Cloud Hystrix 是一个用于处理分布式系统延迟和容错的库,防止雪崩效应。它作为断路器,当服务故障时通过监控短路,返回备用响应,保持系统弹性。主要功能包括服务降级和熔断:
|
2月前
|
自然语言处理 监控 开发者
springCloud之Sentinel流量路由、流量控制、流量整形、熔断降级
springCloud之Sentinel流量路由、流量控制、流量整形、熔断降级
38 0
|
2月前
|
监控
springCloud之Hystrix监控
springCloud之Hystrix监控
18 0
|
2天前
|
Java 微服务 Spring
SpringBoot+Vue+Spring Cloud Alibaba 实现大型电商系统【分布式微服务实现】
文章介绍了如何利用Spring Cloud Alibaba快速构建大型电商系统的分布式微服务,包括服务限流降级等主要功能的实现,并通过注解和配置简化了Spring Cloud应用的接入和搭建过程。
SpringBoot+Vue+Spring Cloud Alibaba 实现大型电商系统【分布式微服务实现】
|
30天前
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
Spring Cloud Alibaba 发布了 Scheduling 任务调度模块 [#3732]提供了一套开源、轻量级、高可用的定时任务解决方案,帮助您快速开发微服务体系下的分布式定时任务。
14243 19
|
2月前
|
人工智能 Java Spring
使用 Spring Cloud Alibaba AI 构建 RAG 应用
本文介绍了RAG(Retrieval Augmented Generation)技术,它结合了检索和生成模型以提供更准确的AI响应。示例中,数据集(包含啤酒信息)被加载到Redis矢量数据库,Spring Cloud Alibaba AI Starter用于构建一个Spring项目,演示如何在接收到用户查询时检索相关文档并生成回答。代码示例展示了数据加载到Redis以及RAG应用的工作流程,用户可以通过Web API接口进行交互。
52443 66