前言:微服务架构应用的特色就是多服务,而服务层之间经过网络进行通讯,从而支撑起整个应用系统,因此,各个微服务之间不可避免的存在耦合依赖关系。但任何的服务应用实例都不可能永远的健康或网络不可能永远的都相安无事,因此一旦某个服务或局部业务发生了故障,会致使系统的不可用,咱们知道当故障累积到必定程度就会形成系统层面的灾害,也就是级联故障,也叫雪崩效应,因此微服务须要在故障累计到上限以前阻止或疏通这些故障以保证系统的稳固安全,在市面上已经有不少这样的框架来解决这样的问题,如Twitter的Finagle、Netflix的Hystrix和Google的Stubby等,下面就简单介绍下Hystrix和Hystrix在SpringCloud中的应用。html
Hystrix(https://github.com/Netflix/Hystrix)是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提高系统的可用性、容错性与局部应用的弹性,是一个实现了超市机制和断路器模式的工具类库。java
一、包裹请求:使用HystrixCommand包裹对依赖的调用逻辑,每一个命令在独立的线程中执行,使用了设计模式中的“命令模式”;
二、跳闸机制:当某服务的错误率超过必定阈值时,Hystrix能够自动或者手动跳闸,中止请求该服务一段时间;
三、资源隔离:Hystrix为每一个依赖都维护了一个小型的线程池(或者信号量)。若是该线程已满,则发向该依赖的请求就会被当即拒绝,而不是排队等候,从而加速失败断定;
四、监控:Hystrix能够近乎实时地监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等;
五、回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑,回退逻辑由开发人员自行提供,如返回一个缺省值;
六、自我修复:断路器打开一段时间后,会自动进入“半开”状态,此时断路器可容许一个请求访问依赖的服务,若请求成功,则断路器关闭,不然断路器转为“打开”状态;git
①、建立基于Eureka和Ribbon的服务端 eureka-ribbon-server和两个客户端生产者 eureka-ribbon-client2、消费者:复制项目eureka-ribbon-client,将AritfactId修改成eureka-hystrix-client;github
②、在消费者中添加依赖:web
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
③、在启动类ClientApplication上添加@EnableHystrix或@EnableCircuitBreaker;spring
④、修改HystrixController,在其中添加getUser方法,并添加熔断回调方法注解及回调方法:设计模式
@HystrixCommand(fallbackMethod = "getDefaultUser")
@RequestMapping("/getUser")
public String getUser() {
return restTemplate.getForObject("http://client-87/getUser", String.class);
}
private String getDefaultUser() {
System.out.println("熔断,默认回调函数");
return "{\"username\":\"admin\",\"age\":\"-1\"}";
}
⑤、分别启动eureka-ribbon-server、eureka-ribbon-client二、eureka-hystrix-client,调用localhost:8765/getUser,如图:安全
⑥、关掉eureka-ribbon-client2后,再次调用,发现熔断器调用了回调函数,如图:网络
关于Hystrix的配置属性,能够自行测试了解:https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#configuration架构
而咱们如何知道hystrix是否开启,能够经过SpringBoot Actuator组件查看,注意:出发回调并非hystrix打开,他的状态还处在关闭,若失败率达到阈值(默认为5秒内20次失败)后才会打开;
一般状况下的Hystrix是经过注解@HystrixCommand的fallbackMethod属性实现回调的,而在Feign中,因为Feign是用借口实现的声明式Rest,因此Hystrix的通用方法在这里就不适用于Feign了,实际上在Feign与SpringCloud的依赖库中已经默认的将Hystrix加入其中了,如图:
那么,该怎么实现呢?
pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
application.properties属性配置文件:
server.port=8762
spring.application.name=client-8762
#默认feign的hystrix为关闭状态
feign.hystrix.enabled=true
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
启动类添加@EnableFeignClients,控制层经过注入feign的接口去完成声明式调用:
feign的接口:
package com.cn.feign; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; //接口类上加入的注解中添加属性fallback,指定回调类 @FeignClient(name = "CLIENT-87",fallback = FeignClientFallback.class) public interface UserFeign { @RequestMapping("/getUser") public String getUser(); }
建立回调类:
package com.cn.feign; import org.springframework.stereotype.Component; /** * @Description: 回调实现类 * @Param: * @return: * @Author: * @Date: 2018/6/19 */ @Component class FeignClientFallback implements UserFeign { @Override public String getUser() { System.out.println("熔断,默认回调函数"); return "{\"username\":\"admin\",\"age\":\"-1\"}"; } }
2.测试结果以下:
在未关闭生产者服务实例时:
关闭实例后:
代码示例:https://gitee.com/lfalex/springcloud-example( eureka-hystrix-client、 eureka-feign-hystrix-client、 eureka-ribbon-client2、 eureka-ribbon-server)
参考书籍:《SpringCloud与Docker微服务架构实战》周力著