(到断路器啦!继续加油)
在微服务架构中,根据业务来拆分成一个个服务,服务与服务之间可以相互调用(RPC),在Spring Cloud中可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用性,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,而服务的调用方不知道问题出现故障,若此时调用请求不断增加,最后就会等待故障的依赖方响应形成任务的积压,最终导致自身服务的瘫痪。由于服务和服务之间的依赖性,故障会传播,会对整个微服务系统造成严重的后果,就是说的服务故障的“雪崩”。
而Spring Cloud Hystrix解决了这些问题,防止对某一故障服务持续进行访问,它实现了线程隔离、断路器等一系列的服务保护功能。它是基于Netflix的Hystrix实现的,该框架的目标是通过控制那些访问远程系统,服务和第三方库的节点,而从达到对延迟和故障强大的容错能力。
Hystrix具备了服务降级,服务熔断,线程隔离,请求缓存,请求合并以及服务监控的功能。
断路器:在分布式架构中,当某个服务发生故障时,通过断路器的故障监控,向服务调用方返回一个错误响应,而不是长时间的等待,这样就可以避免线程因调用故障服务而长时间不释放,避免故障在分布式架构中蔓延。
示意图:
在微服务架构下,通常会有多个层次的服务调用,下图是浏览器通过API访问后台服务器的示意图,一个微服务的超时失败可能导致瀑布式连锁反应,Hystrix可以通过断路器防止这种情况。由于B服务出现某些错误,导致所有访问B服务的请求都会超时,当调用失败的超时达到一个阈值(5秒之内20次失败),链路B就会处于open状态。所有后续对B服务的调用都会停止,取而代之的是Hystrix提供的一个Fallback消息(可由开发者自定义)。
open的链路可以让被淹没或者错误的服务有时间修复,fallback可以是另一个Hystrix保护的调用,可以是静态的数据,也可以是合法的空值,Fallbacks可以组成链式结构。所以最底层调用其它业务服务的第一个fallback是静态数据。
Bibbon+Hystrix
- 添加配置:添加断路器Hystrix
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
- 服务注册
@EnableHystrix开启Hystrix断路器监控
@EnableHystrix @EnableDiscoveryClient @SpringBootApplication public class RibbonConsumerApplication { @LoadBalanced @Bean RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(RibbonConsumerApplication.class, args); } }
- 消费提供者方法
@HystrixCommand(fallbackMethod="defaultStores")注解创建了熔断器的功能,并指定了defaultStores的熔断方法
@RestController public class ConsumerController { @Autowired private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "defaultStores") @GetMapping(value = "/hello") public String hello() { return restTemplate.getForEntity("http://eureka-provider/", String.class).getBody(); } public String defaultStores() { return "Ribbon + hystrix ,提供者的服务挂了"; } }
@HystrixCommand方法表明为hystrix的包裹,可以对依赖服务进行降级,隔离,快速失败,快速重试
- fallbackMethod降级方法
- commandProperties普通配置属性,可以配置HystrixCommand对应的属性,例如是采用线程池还是信号量隔离、熔断器熔断规则等
- ignoreExceptions忽略的异常,默认HystrixBadRequestException不计入失败
- groupKey()组名称,默认使用类名称
- commandKey()命令名称,默认使用方法名称
- 测试断路器
服务已被注册
浏览器访问http://localhost:9000/hello F5刷新,一切正常
此时停止provider-1的服务,端口8081,再次访问http://localhost:9000/hello时,断路器生效了,因为8081的服务挂掉了,所以会返回一个fallback消息
Feign+Hystrix
- 添加依赖
Feign是自带断路器的,但是在Dalston版本的Spring Cloud中没有默认打开,需要在配置文件中添加如下
feign:
hystrix:
enabled: true
- 服务注册
修改homeClient(),添加fallbackFactory指定新建的HystrixClientFallbackFactory类
@FeignClient(value ="eureka-provider",fallbackFactory = HystrixClientFallbackFactory.class) public interface HomeClient { @GetMapping("/") String consumer(); }
新建的HystrixClientFallbackFactory类,
@Component public class HystrixClientFallbackFactory implements FallbackFactory<HomeClient> { @Override public HomeClient create(Throwable throwable) { return () -> "Feign + hystrix ,提供者服务挂了"; } }
- 测试
结果同上
Hystrix Dashboard:作为断路器状态的一个组件,提供了数据监控和友好的图形化界面
Ribbon+Hystrix Dashboard
- 添加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- hystrix 断路器 仪表盘 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency>
- 开启HD
在启动类添加注解@EnableHystrixDashboard启动HD,@EnableHystrix启动Hystrix也是必须的
@EnableHystrix @EnableDiscoveryClient @EnableHystrixDashboard @SpringBootApplication public class RibbonConsumerApplication { @LoadBalanced @Bean RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(RibbonConsumerApplication.class, args); } }
- 声明断路点:通过@HystrixCommand声明
@RestController public class ConsumerController { @Autowired private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "defaultStores") @GetMapping(value = "/hello") public String hello() { return restTemplate.getForEntity("http://eureka-provider/", String.class).getBody(); } public String defaultStores() { return "Ribbon + hystrix Dashboard ,提供者服务挂了"; } }
启动server--provider-1/2/3--hystrixDashboard
访问http://localhost:9000/hystrix,获取hystrix Dashboard信息,默认最大打开5个终端获取监控信息,可以增加Delay参数指定获取监控数据的间隔时间。
Hystrix Dashboard monitor界面,访问http://localhost:9000/hello并不断F5刷新,可以得到如下
参考:https://www.w3cschool.cn/spring_cloud/spring_cloud-t2k62ixi.html
附上原作者源码:https://github.com/souyunku/spring-cloud-examples/tree/master/spring-cloud-hystrix-dashboard