1.说到隔离、熔断、降级,最出名的就是 Netflix 开源的 Hystrix 组件,Hystix官方对它描述为:Hystrix是一个延迟和容错库,旨在隔离远程系统、服务和第三方库,阻止级联故障,在复杂系统中实现恢复能力。
2.下图应用从单块到微服务,系统被拆分为多个,那么产生了个问题,就是微服务的可用性,假设单块应用的可用性是 99.99%,如果被拆分为30个微服务后,总体的可用性是多少,答案是 99.7%,每月2小时宕机时间,实际情况可能更长,30个微服务可用性算法是 99.99%的30阶乘(30个99.99%相乘)。

在这里插入图片描述

3.凡是依赖都可能会失败

当用户请求 A、P、H、I 四个服务获取数据时,在正常流量下系统稳定运行,如果某天系统进来大量流量,其中服务 I 出现 CPU、内存占用过高等问题,结果导致服务 I 出现延迟、响应过慢,随着请求的持续增加,服务 I 承受不住压力导致内部错误或资源耗尽,一直不响应,此时更糟糕的是其他服务对 I 有依赖,那么这些依赖 I 的服务一直等待 I 的响应,也会出现请求堆积、资源占用,慢慢扩散到所有微服务,引发雪崩效应。
在这里插入图片描述

4.为什么服务要进行隔离、熔断、降级?当服务出现异常时可以和其他服务隔离开来,不影响其他服务
  • 隔离:将请求封装在HystrixCommand中,然后这些请求在一个独立的线程中执行,每个依赖服务维护一个小的线程池(或信号量),在调用失败或超时的情况下可以断开依赖调用或者返回指定逻辑
  • 熔断:当HystrixCommand请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务,断路器保持在开路状态一段时间后(默认5秒),自动切换到半开路状态(HALF-OPEN),这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED),否则重新切换到开路状态(OPEN)
  • 降级:服务降级是指当请求后端服务出现异常的时候, 可以使用fallback方法返回的值
5.基本的容错模式
  • 1.主动超时:Http请求主动设置一个超时时间,超时就直接返回,不会造成服务堆积
  • 2.限流:限制最大并发数
  • 3.熔断:当错误数超过阈值时快速失败,不调用后端服务,同时隔一定时间放几个请求去重试后端服务是否能正常调用,如果成功则关闭熔断状态,失败则继续快速失败,直接返回。(此处有个重试,重试就是弹性恢复的能力)
  • 4.隔离:把每个依赖或调用的服务都隔离开来,防止级联失败引起整体服务不可用
  • 5.降级:服务失败或异常后,返回指定的默认信息
    在这里插入图片描述
5.Hystrix 容错的流程图

在这里插入图片描述
上面有 9 个步骤,下面分别讲解每一步骤:

  • 1.每个请求都会封装到 HystrixCommand 中
  • 2.请求会以同步或异步的方式进行调用
  • 3.判断熔断器是否打开,如果打开,它会直接跳转到 8 ,进行降级
  • 4.判断线程池/队列/信号量是否跑满,如果跑满进入降级步骤8
  • 5.如果前面没有错误,就调用 run 方法,运行依赖逻辑
  • 5.运行方法可能会超时,超时后从 5a 到 8,进行降级
  • 6.运行过程中如果发生异常,会从 6b 到 8,进行降级
  • 6.运行正常会进入 6a,正常返回回去,同时把错误或正常调用结果告诉 7 (Calculate Circuit Health)
  • 7.Calculate Circuit Health它是 Hystrix 的大脑,是否进行熔断是它通过错误和成功调用次数计算出来的
  • 8.降级方法(8a没有实现降级、8b实现降级且成功运行、8c实现降级方法,但是出现异常)
  • 8a.没有实现降级方法,直接返回异常信息回去
  • 8b.实现降级方法,且降级方法运行成功,则返回降级后的默认信息回去
  • 8c.实现降级方法,但是降级也可能出现异常,则返回异常信息回去
6.容错理念
  • 凡是依赖都可能会失败
  • 凡是资源都有限制(CPU、内存、线程池)
  • 网络并不靠谱
  • 延迟是应用稳定性最大杀手(可能由于延迟最终拖垮整个微服务,给服务设置一个超时时间来解决延迟引起的问题)
7.Hystrix Dashboard 仪表盘监控所有服务熔断情况
  • 图中左边区域,Hosts表示有234个实例,Circuit Open(76)表示有76个实例打开了熔断开关,进入熔断状态,有158个实例没有进入熔断状态,右边的同理,但是右边所有的实例都处理熔断状态,所有请求都被拒绝,这种情况比较严重
    在这里插入图片描述

下面是 Hystrix 的代码实践,以上的相关概念,可以更好的帮助我们使用 Hystrix ,下面会创建一个简单的项目,引入spring-cloud-starter-netflix-hystrix组件,在控制器的方法中手动写一个异常,同时给该方法添加一个 HystrixCommand降级方法,指定降级信息,访问该方法时,触发异常,返回降级信息

7.创建SpringBoot项目,引入Hystrix依赖:
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

在启动主类上添加如下代码:

@RestController
@EnableHystrix
@SpringBootApplication
public class HystrixDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(HystrixDemoApplication.class, args);
	}

	//通过HystrixCommand注解,手动指定一个降级方法,出现异常后会调用该降级方法
	@RequestMapping("/getName")
	@HystrixCommand(fallbackMethod = "getNameFallback")
	public String getName(String username) throws Exception{
		if(username.equals("zhuyu")){
			return "this is zhuyu";
		}else{
			throw new Exception();
		}
	}

	/**
	 * 出错后会调用该降级方法,返回指定的信息
	 * @param username
	 * @return
	 */
	public String getNameFallback(String username){
		return " this username is not exist ";
	}
}

运行程序,访问 http://localhost:8080/getName?username=zhuyu ,正常,没有触发降级
在这里插入图片描述
再访问 http://localhost:8080/getName?username=zhuyu11 ,可以看到返回了降级后设置的信息
在这里插入图片描述
好了,最简单的降级代码完成了。
上面仅演示了HystrixCommand的降级配置,还有很多其他配置,如:指定HystrixCommand的超时时间、线程池key以及线程池和队列大小,大家可以自行实验

@HystrixCommand(fallbackMethod = "getNameFallback", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "4000")
        }, 
        threadPoolKey = "hystrixDemoThreadPool",
        threadPoolProperties = {
                @HystrixProperty(name = "coreSize", value = "30"),
                @HystrixProperty(name = "maxQueueSize", value = "10")
        })

Hystrix不仅仅有熔断、降级,实际生产环境中 Hystrix 需要与网关和Feign集成,对服务间的调用做熔断、降级
还有Hystrix Dashborad仪表盘,用可视化的面板展示系统在一段时间内发生的请求情况

Hystrix还可以把多个请求合并进行一次性处理,可以减少网络通信与线程池资源,对处理高并发的业务效果较好

网上有位朋友对 Hystrix的熔断、降级、隔离说的也很好:https://www.cnblogs.com/Leo_wl/p/9054906.html

代码已上传至码云,源码,项目使用的版本信息如下:

- SpringBoot 2.0.6.RELEASE
- SpringCloud Finchley.SR2
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐