微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

服务可靠性是微服务架构的关键要素之一。

容错机制包括:隔离、服务熔断、服务回退

微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

一、服务消费者容错思想和模式

1、微服务架构需要考虑服务的可靠性因素,因为服务依赖失败会造成失败扩散,从而形成服务访问的雪崩效应。

微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

A为服务的提供者,B为A服务的消费者,CDE为服务B的消费者,加入A失败,则B失败,从而导致CDE失败,而导致整个服务体系发生雪崩。

两个系统交互图

微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

2、服务隔离

在架构设计中存在一种舱壁隔离模式,就是想舱壁一样对资源或失败的单元进行隔离。本质是对系统或资源进行分割,从而实现当系统发生故障时能够限定传播范围和影响范围,只有出现问题的服务不可用,而其他服务仍然可用。

微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

(1)线程隔离

线程隔离主要通过线程池进行隔离,在实际业务中把业务分类并交给不同的线程池进行处理,当某种线程池处理业务发生问题时,不会扩散到其他线程池。就不会影响到其他业务。

没有使用线程池隔离,会造成雪崩。

微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

使用线程次隔离的场景

微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

(2)进程隔离

就是将系统拆分为多个字系统已实现物理隔离,各系统运行在独立的容器或者JVM中,通过进程隔离,使得某个字系统出现问题不会影响其他子系统。

3、服务熔断

从设计理念上讲,服务熔断也是一种快速失败的具体表现。

微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

Closed:熔断器关闭状态,不对服务调用进行限制,但会对调用失败的次数进行累计,达到一定阀值的时候会启动熔断机制。

Open:熔断器打开的状态,此时服务器的调用将会直接返回错误,不执行正真的网络调用,同时,设置一个时钟选项,当时钟达到一定的时间,会进入半熔状态。

Half-Open:半熔状态,允许一定的服务请求,如果调用都成功或者达到一定的比例,说明链路已经恢复,关闭熔断,否者认为链路仍然存在问题,又回到熔断

4、服务回退

当服务调用发生异常时候,不直接抛出该异常,而是生产另外的处理机制俩应对异常,相当于执行了另外一条路径上的代码或返回一个默认的处理结果,告知消费者当前服务存在问题。

二、使用Hystrix实现服务容错

Spring Cloud Netflix Hystrix实现了服务隔离、服务熔断和服务回退3中服务容错机制。

HystrixCommand是Hystrix中涉依赖的边界进行封装,子类必须实现HystrixCommand提供的子类,并实现两个方法:

run()方法:该方法用于实现锁依赖的业务逻辑、微服务之间的调用。

getFallBacj()方法:该方法用于实现服务回退处理逻辑。

使用Hystrix需要在Maven中引入spring-cloud-starter-hystrix 并在启动类中添加一个注解@EnableCircuitBreker,告诉Spring cloud 希望在该服务中启用Hystrix,可以使用服务熔断和服务回退功能。

1、使用Hystrix实现服务隔离

针对服务隔离,Hystrix组件提供了两种解决方案,即线程池隔离和信号量隔离,都是限制对共享资源的并发访问量。

2、Hystrix线程池隔离

微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

Hytrix可以通过粗粒度进行隔离,也可以通过细粒度进行隔离:服务分组+线程池、服务分组+服务+线程池、混合

(1)服务分组+线程池模式

一个分组配置一个线程池即可。

(2)服务分组+服务+线程池模式

一个分组中的每一个服务配置一个隔离线程池,为不同的命令实现配置不同的线程池名称。

(3)混合

在混合实现模式下,一个服务组配置一个线程池,然后对重要的服务单独设置隔离线程池。

3、Hystrix信号量隔离

线程池隔离和信号量隔离主要区别在于线程池方式下业务请求线程和执行依赖服务的线程不是同一个线程,而信号量方式下这两者使用同一个线程。Hystrix同样提供了HystrixCommandProperies用于配置命令的一些参数,如果将属性execution.isolation.strategy设置为SEMAPHORE,则Hysterix使用信号量而不是默认的线程池来隔离。

三、使用Hystrix实现服务熔断

1、Hystrix允许在一定的窗口时间时间内进行一次重试,重试成功成功则闭合熔断开关,否则开关会一直处于打开状态。

2、使用Hystrix实现服务回退

Hystrix在服务调用失败(异常、拒绝、超时、熔断)时可以执行服务回退逻辑。

微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

四、Hystrix基本原理

1、服务隔离

Hystrix使用命令模式实现类HystrixCommand包装依赖调用逻辑,将每个类型的业务请求封装成对应的命令,每个命令在单独线程中执行,创建好的线程池被放入到ConcurrentHashMap中,当第二次查询请求过来时,可以直接从Map中获取该线程池。

在Hystrix中,执行HystixCommand的方式有4种:

execute()方式:阻塞,当依赖服务正常响应或者抛异常时返回结果。

queue()方式:返回Future对象,通过该对象异步得到返回结果。

observer()方式:返回Observable对象,立即发出请求,在依赖服务正常或抛出异常时,通过Subscriber得到返回结果。

toObservable()方式:返回OBverable对象,丹只有在该对象呗订阅时候才会发出请求,然后依赖服务正常响应或抛出异常,通过注册的Subscriber得到返回结果。

微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

2、服务熔断

Hystix通过HystrixCirCuitBreaker接口定义了服务熔断机制,访问HystrixCircuitBreaker接口有三种方式:

(1)allowRequest()方法

每个请求都会通过该方法判断是否可被执行。

(2)isOpen()方法

返回当前熔断是否打开。

(3)markSuccess()方法

关闭熔断器。

Hystrix整体运行流程图

1.构建HystrixCommand对象,执行业务方法。

2.Hystix检查当前服务器的熔断开关是否开启,若开启,则执行回退方法。

3.若熔断开关处于关闭状态,则检查当前线程池是否能够接受新的请求,若线程池满,则同样执行回退方法。

4.若线程池接受请求,则Hystrix执行run()方法中指定的服务调用逻辑。

5.若服务执行失败,则执行回退方法,并将结果上报监控数据收集器更新服务器健康状况。

6.如服务器执行超时,同样执行回退方法并上报执行结果。

7.若服务执行成功,则返回正常结果。

8.若回退方法执行成功,则返回回退结果。

如回退方法执行失败,则抛出异常。

微服务架构实战学习笔记 第五章 Spring Cloud Netflix Hystrix与服务容错

3、Hystrix配置