“ 什么是熔断、降级?为什么要做熔断、降级?spring cloud体系下熔断降级是如何设计实现的?”
熔断与降级:
在分布式高并发的环境下,后端每个服务之间的依赖关系非常多,层级非常多,如果一个请求依赖后端的服务A,服务A调用B,服务B调用C,如果这个时候服务B出现异常,就会导致大量的请求超时,在并发量很大的情况下,会瞬间消耗到服务器的CPU与内存资源,导致硬件压力大,从而致使整个服务异常,这个情况又称之为服务雪崩。如下图所示: 举个最近比较火的例子解释一下这个熔断: 3月9日美股开盘暴跌,标普500开盘跌7%触发熔断机制,暂停交易15分钟。上诉新闻可以看出几个点,第一个是熔断条件:标普500 ,第二个 熔断阈值:跌7% ,第三个是熔断处理机制:暂停交易15分钟。 对于降级呢?很多人不同的理解,这里我个人认为降级可以为熔断之后的一系列处理措施,也就是熔断为触发条件,降级为处理机制。比如说上面美国熔断处理机制,暂停交易15分钟,这个就是服务降级的一个处理方式,下面还有多个服务降级的处理方式:1、熔断条件触发之后,可以对非核心服务进行限流降级(具体的降级办法,可以通过Hystrix的fallback调整限流接口的阈值)。2、熔断条件触发之后,可以直接拒绝服务或者关停非核心服务。3、熔断条件触发之后,可以转发请求到备用服务上。4、熔断条件触发之后,部分请求可以转发到专门处理异常服务的队列,并根据队列信息进行补偿服务。 本文介绍Netflix开源的Hystrix组件,来具体描述spring cloud体系下,熔断与降级的实现方式。01
—
Hystrix-豪猪
什么是Hystrix:
在分布式环境中,许多服务依赖项中的一些不可避免地会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助您控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止服务之间的级联故障以及提供回退选项来实现这一点,所有这些都提高了系统的总体弹性。
官方文档https://github.com/Netflix/Hystrix/wiki
Hystrix的设计目的:
1、提供对延迟和故障的保护和控制,防止依赖项通过第三方客户端库访问(通常通过网络)。
2、停止复杂分布式系统中的级联故障。
3、故障迅速恢复。
4、在可能的情况下后退并优雅地降级。
5、启用近实时监视、警报和操作控制。
Hystrix是如何设计达成目的:
1、将对外部系统(或“依赖项”)的所有调用包装到HystrixCommand或hystrixobservatablecommand对象中,该对象通常在单独的线程中执行(这是命令模式的示例)。
2、超时调用所需时间超过您定义的阈值。有一个默认值,但对于大多数依赖项,您可以通过“属性”自定义设置这些超时,以便它们略高于每个依赖项的测量99.5%性能。
3、为每个依赖项维护一个小的线程池(或信号量);如果该线程池已满,则为该依赖项指定的请求将立即被拒绝,而不是排队。
4、衡量成功、失败(客户端引发的异常)、超时和线程拒绝。
5、使断路器跳闸,以在一段时间内停止对特定服务的所有请求,手动或自动(如果服务的错误百分比超过阈值)。
6、当请求失败、被拒绝、超时或短路时执行回退逻辑。
7、几乎实时地监视度量和配置更改。
当您使用Hystrix包装每个底层依赖项时,如上图所示的体系结构将更改为类似下图。每个依赖项彼此隔离,在发生延迟时它可以饱和的资源中受到限制,并包含在回退逻辑中,回退逻辑决定当依赖项中发生任何类型的故障时应做出什么响应:springboot集成Hystrix:
1、引入maven配置,修改pom.xml
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>
2、启动文件增加配置
@SpringBootApplication@EnableHystrix@EnableEurekaClientpublic class KayAdminApplication { public static void main(String[] args) { SpringApplication.run(KayAdminApplication.class, args); }}
3、修改配置参数 application.yml
#feign相关配置feign: hystrix: enabled: true #开启Feign熔断#hystrix相关配置hystrix: threadpool: default: coreSize: 1000 #线程池大小 command: default: fallback: isolation: semaphore: maxConcurrentRequests: 1000 #设置调用线程产生的HystrixCommand.getFallback()方法的允许最大请求数目,如果达到最大并发数目,后续请求将会被拒绝,如果没有实现回退,则抛出异常 execution: isolation: thread: timeoutInMilliseconds: 6000 #超时时间 metrics: rollingStats: timeInMilliseconds: 2000 #默认值10000,滚动窗口的时间范围 circuitBreaker: requestVolumeThreshold: 10000 #默认值20,设置在一个滚动窗口中,打开断路器的最少请求数 errorThresholdPercentage: 80 #出错百分比阈值,当达到此阈值后,开始短路 sleepWindowInMilliseconds: 1000 #短路多久以后开始尝试是否恢复,默认值 5000,休眠期的持续时间
3、结合feigin使用
@FeignClient(value = "service-uid", fallbackFactory = ServiceUidHystric.class)@Servicepublic interface ServiceUidFeign {
@RequestMapping(value = "/service/get/ids", method = RequestMethod.POST) Result getNextIds(@RequestBody GenerateIdVO generateIdVO);
@RequestMapping(value = "/service/check/ids", method = RequestMethod.POST) Result checkIds(@RequestBody GenerateIdVO generateIdVO);
}
4、开发fallback模块
public interface ServicetUidFallBackFactory extends ServiceUidFeign {
}
@Componentpublic class ServiceUidHystric implements FallbackFactory<ServiceUidFeign> { private static final Logger logger = LoggerFactory.getLogger(ServiceUidHystric.class);
@Override public ServiceUidFeign create(Throwable throwable) { return new ServicetUidFallBackFactory(){ @Override public Result getNextIds(@RequestBody GenerateIdVO generateIdVO){ //这里主要为降级的具体处理逻辑,demo只记录异常信息,并返回异常信息 logger.error("http://service-uid/service/get/ids:request fail:{}", JSON.toJSONString(generateIdVO),throwable.getMessage()); return ResultUtils.internalError("Service fuses."); }
@Override public Result checkIds(@RequestBody GenerateIdVO generateIdVO){ logger.error("http://service-uid/service/check/ids:request fail:{}", JSON.toJSONString(generateIdVO),throwable.getMessage()); return ResultUtils.internalError("Service fuses."); } }; }}
周星星 互联网从业人员 资深峡谷战士
本文内容为原创内容
未经授权,禁止转载