Hystrix分布式系统限流、降级、熔断框架(二)

三、Hystrix容错

???????Hystrix的容错主要是通过添加容许延迟和容错方法,帮助控制这些分布式服务之间的交互。 还通过隔离服务之间的访问点,阻止它们之间的级联故障以及提供回退选项来实现这一点,从而提高系统的整体弹性。Hystrix主要提供了以下几种容错方法:

  • 资源隔离
  • 熔断
  • 降级

1、资源隔离-线程池

2、资源隔离-信号量

线程池和信号量隔离比较
? 线程切换 支持异步 支持超时 支持熔断 限流 开销
信号量
线程池

???????当请求的服务网络开销比较大的时候,或者是请求比较耗时的时候,我们最好是使用线程隔离策略,这样的话,可以保证大量的容器(tomcat)线程可用,不会由于服务原因,一直处于阻塞或等待状态,快速失败返回。而当我们请求缓存这些服务的时候,我们可以使用信号量隔离策略,因为这类服务的返回通常会非常的快,不会占用容器线程太长时间,而且也减少了线程切换的一些开销,提高了缓存服务的效率。

???????线程池适合绝大多数的场景,对依赖服务的网络请求的调用;信号量适合访问不是对外部依赖的访问,而是对内部的一些比较复杂的业务逻辑的访问,只要做信号量的普通限流就可以了。

3、熔断

为什么要使用断路器

???????在分布式架构中,一个应用依赖多个服务是非常常见的,如果其中一个依赖由于延迟过高发生阻塞,调用该依赖服务的线程就会阻塞,如果相关业务的QPS较高,就可能产生大量阻塞,从而导致该应用/服务由于服务器资源被耗尽而拖垮。另外,故障也会在应用之间传递,如果故障服务的上游依赖较多,可能会引起服务的雪崩效应。

熔断器工作的详细过程如下:

第一步,调用allowRequest()判断是否允许将请求提交到线程池

1、如果熔断器强制打开,circuitBreaker.forceOpen为true,不允许放行,返回。

2、如果熔断器强制关闭,circuitBreaker.forceClosed为true,允许放行。此外不必关注熔断器实际状态,也就是说熔断器仍然会维护统计数据和开关状态,只是不生效而已。

第二步,调用isOpen()判断熔断器开关是否打开

1、如果熔断器开关打开,进入第三步,否则继续;

2、如果一个周期内总的请求数小于circuitBreaker.requestVolumeThreshold的值,允许请求放行,否则继续;

3、如果一个周期内错误率小于circuitBreaker.errorThresholdPercentage的值,允许请求放行。否则,打开熔断器开关,进入第三步。

第三步,调用allowSingleTest()判断是否允许单个请求通行,检查依赖服务是否恢复

1、如果熔断器打开,且距离熔断器打开的时间或上一次试探请求放行的时间超过circuitBreaker.sleepWindowInMilliseconds的值时,熔断器器进入半开状态,允许放行一个试探请求;否则,不允许放行。

此外,为了提供决策依据,每个熔断器默认维护了10个bucket,每秒一个bucket,当新的bucket被创建时,最旧的bucket会被抛弃。其中每个blucket维护了请求成功、失败、超时、拒绝的计数器,Hystrix负责收集并统计这些计数器。

执行策略如下:

Hystrix遇到一个超时/失败请求,此时启动一个10s的窗口,后续的请求会进行如下判断:

(1)查看失败次数是否超过最小调用次数

  • 如果没有超过,则放行请求。
  • 如果超过最小请求数,继续下面逻辑

(2)判断失败率是否超过一个阈值,这里错误是指超时和失败两种。

  • 如果没有超过,则放行
  • 如果超过错误阈值,则继续下面逻辑

(3)熔断器断开

  • 请求会直接返回失败。
  • 会开一个5s的窗口,每隔5s调用一次请求,如果成功,表示下游服务恢复,否则继续保持断路器断开状态。

4、降级

???????降级,通常指务高峰期,为了保证核心服务正常运行,需要停掉一些不太重要的业务,或者某些服务不可用时,执行备用逻辑从故障服务中快速失败或快速返回,以保障主体业务不受影响。

???????要支持回退或降级处理,一般是查询操作,可以重写HystrixCommand的getFallBack方法或HystrixObservableCommand的resumeWithFallback方法,通常不建议在回退逻辑中执行任何可能失败的操作。

Hystrix在以下几种情况下会走降级逻辑:

  • 执行construct()或run()抛出异常
  • 熔断器打开导致命令短路
  • 命令的线程池和队列或信号量的容量超额,命令被拒绝
  • 命令执行超时

???????如果降级逻辑中需要发起远程调用,建议重新封装一个HystrixCommand,使用不同的ThreadPoolKey,与主线程池进行隔离。

四、Hystrix配置

???????Hystrix默认使用Netflix Archaius进行配置管理,项目中使用zookeeper作为配置源,通过archaius-zookeeper实现hystrix命令、熔断器、线程池、监控等参数的动态配置,根据生产环境需要动态调整hystrix参数,实现了对微服务的治理。

???????每个Hystrix参数都有4个地方可以配置,优先级从低到高如下,如果每个地方都配置相同的属性,则优先级高的值会覆盖优先级低的值:

  • 内置全局默认值:写死在Hystrix代码里的默认值,如HystrixCommandProperties.default_executionTimeoutInMilliseconds属性
  • 动态全局默认属性:全局配置文件读到的默认值
  • 内置实例默认值:创建HystrixCommand时,通过注解或者给父类构造器传参的方式设置的默认值
  • 动态配置实例属性:通过属性文件配置特定实例的值

以hystrix命令sns.grassSearchIndex执行的超时时间设置为例,属性的优先级从低到高为

default_executionTimeoutInMilliseconds=1000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=500
HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(1000)
hystrix.command.sns.grassSearchIndex.execution.isolation.thread.timeoutInMilliseconds=1500

Command 配置

# 隔离策略: 可选THREAD|SEMAPHORE,默认TREAD
hystrix.command.default.execution.isolation.strategy=TREAD
# 服务超时时间,单位毫秒,默认1000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000
# 服务sns.grassSearchIndex超时时间
hystrix.command.sns.grassSearchIndex.execution.isolation.thread.timeoutInMilliseconds=2000
# 是否打开超时检测,默认启用true
hystrix.command.default.execution.timeout.enabled=true
# 使用信号量隔离时qps阈值,后续的请求会被拒,默认10
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests=10

熔断器(Circuit Breaker)配置

# 是否打开断路器,默认开启true
hystrix.command.default.circuitBreaker.enabled=true
# 断路器检测的基础请求值,只有时间窗口内的请求数达到这个阈值时,才会判定错误率,否则比如只有一两个请求,即便都失败了,也不会打开断路器,因为基数太少了,默认20
hystrix.command.default.circuitBreaker.requestVolumeThreshold=100
# 错误百分比,超过就会短路,默认值50
hystrix.command.default.circuitBreaker.errorThresholdPercentage=75
# 指的是从断路器打开状态到半开半闭状态需要的时间,即断路后,需要等多久才能放一个请求进来,默认值5000
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=5000

# Metrics
# 统计的时间窗口大小,默认10000
hystrix.command.default.metrics.rollingStats.timeInMilliseconds=10000
# 时间窗口的桶的数目,必须能被时间窗口大小整除,否则报错,每个bucket包含success,failure,timeout,rejection的次数的统计信息,默认10
hystrix.command.default.metrics.rollingStats.numBuckets=10
# 每一次检测的间隙。因为就算分窗口统计错误率,也会很占cpu,所以每一次统计都会等一个时间间隔再开始,默认500
hystrix.command.default.metrics.healthSnapshot.intervalInMilliseconds=500
# 带rollingPercentile的都表示调用时延的统计,该选项表示是否打开时延统计,比如说95分位99分位等,如果关闭都返回-1,默认true
hystrix.command.default.metrics.rollingPercentile.enabled=true
# 时延统计的时间窗口,默认60000
hystrix.command.default.metrics.rollingPercentile.timeInMilliseconds=60000
# 时延统计的桶数目
hystrix.command.default.metrics.rollingPercentile.numBuckets=6
# 时延统计的桶大小,时延统计每一个桶只维持最新的该数值的请求的数据,早一些的将会被覆盖。如果bucket size=100,window=10s,若这10s里有500次执行,只有最后100次执行会被统计到bucket里去,增加该值会增加内存开销以及排序的开销,默认100
hystrix.command.default.metrics.rollingPercentile.bucketSize=100

线程池(ThreadPool)配置

# 默认核心线程数,不会变,默认10
hystrix.threadpool.default.coreSize=30
# userLogin隔离线程池核心线程数
hystrix.threadpool.userLogin.coreSize=20
# 等待队列,还超就会被拒,这个数值无法动态修改,默认-1
hystrix.threadpool.default.maxQueueSize=50000
# userLogin隔离线程池等待队列
hystrix.threadpool.userLogin.maxQueueSize=3000
# 进入queue时被拒的概率值,即便是没有达到maxQueueSize。这个为了弥补上面无法动态修改的不足。可以通过这个概率值来控制队列大小
hystrix.threadpool.default.queueSizeRejectionThreshold=45000
#线程池统计指标的时间,默认10000
hystrix.threadpool.default.metrics.rollingStats.timeInMilliseconds=10000
#将rolling window划分为n个buckets,默认10
hystrix.threadpool.default.metrics.rollingStats.numBuckets=10

五、服务监控

Hystrix Dashboard

???????Hystrix Dashboard主要用来实时监控Hystrix的各项指标信息。通过Hystrix Dashboard反馈的实时信息,可以帮助我们快速发现系统中存在的问题。

???????通过 https://search.maven.org 站点下载standalone-hystrix-dashboard,运行jar包后访问http://localhost:7979/hystrix-dashboard/,即可进入hystrix dashboard页面

nohup java -jar -DserverPort=7979 -DbindAddress=localhost standalone-hystrix-dashboard-1.5.3-all.jar &

???????集群环境监控可使用Netflix提供的turbine进行监控。通过maven公服https://search.maven.org下载并部署war包turbine-web,修改集群节点配置,将turbine地址http://localhost:${port}/turbine.stream?cluster=default添加监控到dashboard

turbine.aggregator.clusterConfig=default
turbine.instanceUrlSuffix=:8080/gateway/hystrix.stream
turbine.ConfigPropertyBasedDiscovery.test.instances=10.66.70.1,10.66.70.2,10.66.70.3

原文地址:https://www.cnblogs.com/qingfengEthan/p/12113115.html

时间: 2024-10-14 05:25:56

Hystrix分布式系统限流、降级、熔断框架(二)的相关文章

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

在之前的<使用Sentinel实现接口限流>一文中,我们仅依靠引入Spring Cloud Alibaba对Sentinel的整合封装spring-cloud-starter-alibaba-sentinel,就完成了对所有Spring MVC接口的限流控制.然而,在实际应用过程中,我们可能需要限流的层面不仅限于接口.可能对于某个方法的调用限流,对于某个外部资源的调用限流等都希望做到控制.呢么,这个时候我们就不得不手工定义需要限流的资源点,并配置相关的限流策略等内容了. 今天这篇我们就来一起学

Spring Cloud微服务Sentinel+Apollo限流、熔断实战

在Spring Cloud微服务体系中,由于限流熔断组件Hystrix开源版本不在维护,因此国内不少有类似需求的公司已经将眼光转向阿里开源的Sentinel框架.而以下要介绍的正是作者最近两个月的真实项目实践过程,这中间被不少网络Demo示例级别水文误导过,为了以正视听特将实践过程加以总结,希望能够帮到有类似需要的朋友! 一.Sentinel概述 在基于Spring Cloud构建的微服务体系中,服务之间的调用链路会随着系统的演进变得越来越长,这无疑会增加了整个系统的不可靠因素.在并发流量比较高

鹰眼跟踪、限流降级,EDAS的微服务解决之道

本文主要从服务化的起源开始讲起,围绕EDAS介绍这些年来,随着阿里庞大的电商技术平台流量和并发不断攀升过程中,中间件的微服务技术面临的一系列挑战及解决方法.同时,也会向读者介绍历次双十一背后,EDAS服务化技术的演进历程. 服务化的起源 微服务的解决之道 海量微服务的挑战 关于作者 以下为精彩内容整理: 服务化的起源 阿里巴巴前期技术现状 当时阿里巴巴技术团队规模有500人左右,整个技术网站使用单一War应用,基于传统应用开发架构,业务每年翻倍增长. 我们面临着非常多的问题: 上百人维护一个核心

分布式系统中的限流与熔断

在应对秒杀.大促.双 11.618 等高性能压力的场景时,限流已经成为了标配技术解决方案,为保证系统的平稳运行起到了关键性的作用.不管应用场景是哪种,限流无非就是针对超过预期的流量,通过预先设定的限流规则选择性的对某些请求进行限流“熔断”. 1. 限流 1.1 单机限流 a>>限制并发量 import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.con

使用springcloud gateway搭建网关(分流,限流,熔断)

Spring Cloud Gateway Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式. Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter

JavaWeb限流QPS简易框架

Java Web利用filter实现拦截请求,统计信息.并控制单台机器QPS. /** * 网络流量控制器 */ public class TrafficFilter implements Filter { private ITrafficStatic trafficStatic; private ITrafficHandler trafficHandler; @Override public void init(FilterConfig filterConfig) throws Servlet

限流和降级(下) | 如何打造平台稳定性能力(二)

摘要: 上一期我们谈到了阿里巴巴早期是通过通过在 Nginx 上实现的扩展组件TMD(taobao missile defense淘宝×××防御系统)实现了接入层限流的主要工作,TMD系统可通过域名类限流.cookie限流.黑名单以及一些安全策略等很好的实现了在接入层的限流措施. 上一期我们谈到了阿里巴巴早期是通过通过在 Nginx 上实现的扩展组件TMD(taobao missile defense淘宝×××防御系统)实现了接入层限流的主要工作,TMD系统可通过域名类限流.cookie限流.黑

.Net Core的API网关Ocelot的使用(二)[负载,限流,熔断,Header转换]

网关的负载均衡 当下游拥有多个节点的时候,我们可以用DownstreamHostAndPorts来配置 { "UpstreamPathTemplate": "/Api_A/{controller}/{action}", "DownstreamPathTemplate": "/api/{controller}/{action}", "DownstreamScheme": "https",

Dubbo学习系列之十(Sentinel之限流与降级)

各位看官,先提个问题,如果让你设计一套秒杀系统,核心要点是啥???我认为有三点:缓存.限流和分离.想当年12306大面积崩溃,还有如今的微博整体宕机情况,感觉就是限流降级没做好,"用有限的资源响应过量请求"——这就是限流降级的核心.限流降级组件,当今开源界应该是Hystrix最为出名,这也得益于SpringCloud的流行,当然,挑战者总是有的,于是Sentinel横空出世,正因实际生产使用中似乎并不多见,所以才有必要拿来一用,不然就脱离了此系列文章的主旨了,就是要见些不一样的风景!