接上篇《16.超时机制,断路器模式简介》  Spring Cloud版本为Finchley.SR2版

上一篇我们介绍了超时机制以及断路器模式,并且引申出了Spring Cloud的断路器组件Hystrix。本篇我们来学习Hystrix的基础知识。
本部分官方文档:https://cloud.spring.io/spring-cloud-static/Finchley.SR2/single/spring-cloud.html#_circuit_breaker_hystrix_clients

一、Hystrix断路器简介

Hystrix的读音是 [hIst'rIks](嗨斯捶克斯~哈哈哈),在英文里面是豪猪的意思,大概是下面这个:

豪猪身上有很多刺,这些刺可以很好的保护自己,所以开发团队给这个保护组件起名为Hystrix。

首先我们来看一下Spring Cloud官方文档对Hystrix的介绍:
Netflix创建了一个名为Hystrix的库,实现了断路(熔断)器的模式。一般在微服务架构通常有多层服务调用:

“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝,这里默认服务5秒失败20次就认为服务异常),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩的发生:

拥有一个断路器可以停止级联故障,并且给予失败的服务有自我恢复的时间。回退机制中的备选响应(FallBack)可以是另外一个服务,或者是一个静态数据,当然也可以是一个空值。

二、引入并使用Hystrix

我们需要引入Hystrix组件的话,在pom文件中添加spring-cloud-starter-netflix-hystrix的依赖即可:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

然后在启动类上添加@EnableCircuitBreaker注解,引入断路器:

@SpringBootApplication
@EnableCircuitBreaker
public class Application {public static void main(String[] args) {new SpringApplicationBuilder(Application.class).web(true).run(args);}}

然后在需要使用断路器进行备选响应的服务上,添加@HystrixCommand注解,并指定服务异常之后回退的具体方法(fallbackMethod):

@Component
public class StoreIntegration {@HystrixCommand(fallbackMethod = "defaultStores")public Object getStores(Map<String, Object> parameters) {//do stuff that might fail}public Object defaultStores(Map<String, Object> parameters) {return /* something useful */;}
}

当调用getStores服务异常的时候,就会自动进行服务降级,调用“fallbackMethod”参数指定的回退方法。
上面例子看起来还是比较简单的,而实际上Hystrix的使用也是这么方便的。那么为什么引入@HystrixCommand就能实现断路器模式呢?
首先我们要知道,@HystrixCommand是由名为“javanica”的Netflix contrib 库提供,什么是“javanica”呢?
javanica是Netflix contrib下的一个子项目,其在github上的仓库地址为:
https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica
我们可以在其github首页的README.md公告中了解到,javanica工程实现了一个HystrixCommandAspect切面类,使用AOP切面机制,处理请求服务的前置和后置逻辑:

<aspects>...<aspect name="com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect"/>...
</aspects>

然后就可以直接使用@HystrixCommand进行服务的直接访问了:

public class UserService {
...@HystrixCommandpublic User getUserById(String id) {return userResource.getUserById(id);}
}
...

那么,说到底,@HystrixCommand其实并不是Hystrix的原生注解(其在com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand包下),而是“javanica”项目对原来的Hystrix进行了改进和封装,使开发者更方便的使用Hystrix。

我们可以直接去Hystrix的github首页,然后在其wiki上(https://github.com/Netflix/Hystrix/wiki/How-To-Use)看看原始的Hystrix是如何使用的:
继承HystrixCommand<T>类,实现run方法,getFallback回退方法:

public class CommandHelloWorld extends HystrixCommand<String> {private final String name;public CommandHelloWorld(String name) {super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));this.name = name;}@Overrideprotected String run() {// a real example would do work like a network call herereturn "Hello " + name + "!";}@Overrideprotected String getFallback() {return "Hello Failure " + name + "!";}
}

或者是继承HystrixObservableCommand<T>类,实现construct方法,resumeWithFallback回退方法:

public class CommandHelloWorld extends HystrixObservableCommand<String> {private final String name;public CommandHelloWorld(String name) {super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));this.name = name;}@Overrideprotected Observable<String> construct() {return Observable.create(new Observable.OnSubscribe<String>() {@Overridepublic void call(Subscriber<? super String> observer) {try {if (!observer.isUnsubscribed()) {// a real example would do work like a network call hereobserver.onNext("Hello");observer.onNext(name + "!");observer.onCompleted();}} catch (Exception e) {observer.onError(e);}}} ).subscribeOn(Schedulers.io());}/*** fallback方法的写法,覆写resumeWithFallback方法* 当调用出现异常时,会调用该降级方法*/@Overridepublic Observable<String> resumeWithFallback() {return Observable.create(new OnSubscribe<String>() {@Overridepublic void call(Subscriber<? super String> observer) {try {if (!observer.isUnsubscribed()) {observer.onNext("Hello Failure");observer.onNext(name + "!");observer.onCompleted();}} catch (Exception e) {observer.onError(e);}}}).subscribeOn(Schedulers.io());}
}

调用的时候调用execute方法即可:

String s = new CommandHelloWorld("World").execute();

也可以使用queue方法异步执行,使用Future<T>类获取相关结果:

Future<String> fs = new CommandHelloWorld("World").queue();
String s = fs.get();

我们要感谢“javanica”项目然我们如此方便的使用Hystrix。

要配置@Hystrixcommand注解,可以使用其commandproperties属性。有关commandproperties属性的相关知识我们后面会详细介绍。

三、实例测试

我们在之前的microserver-consumer-movie工程上进行Hystrix的测试。首先在其pom.xml文件中添加Hystrix的依赖:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

然后在启动类MicroserverSimpleConsumerMovieApplication类添加@EnableCircuitBreaker注解:

package com.microserver.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import com.microserver.config.TestConfiguration;@SpringBootApplication
@EnableCircuitBreaker
@EnableFeignClients
@RibbonClient(name = "microserver-provider-user",configuration=TestConfiguration.class )
public class MicroserverSimpleConsumerMovieApplication {public static void main(String[] args) {SpringApplication.run(MicroserverSimpleConsumerMovieApplication.class, args);}
}

我们还记得之前在MovieController中编写了“/movie/{id}”的服务,方法为findUserById,

@RestController
public class MovieController {//上面代码省略...@Autowiredprivate UserFeignClient userFeignClient;@GetMapping("/movie/{id}")public User findUserById(@PathVariable Long id){return userFeignClient.findById(id);}//下面代码省略...
}

我们准备对这个服务进行异常断路和降级的操作。首先给findUserById方法添加@Hystrixcommand注解,并且配置其服务降级退回方法为“findUserByIdFallback”:

@RestController
public class MovieController {//上面代码省略...@Autowiredprivate UserFeignClient userFeignClient;@GetMapping("/movie/{id}")@HystrixCommand(fallbackMethod = "findUserByIdFallback")public User findUserById(@PathVariable Long id){return userFeignClient.findById(id);}public User findUserByIdFallback(){User user = new User();user.setId(0L);return user;}//下面代码省略...
}

fallbackMethod对应的方法,其中的参数和返回值一定要和原来的服务相同。
然后重启movie工程、user工程以及eureka Server工程:

在eureka Server首页可以看到两个工程都是UP状态:

此时我们通过movie工程的“movie/{id}”服务来获取用户信息,请求id为1的用户信息:

可以看到此时反馈是正常的。这里要注意的是,我们首次访问的时候有可能会进降级方法,这是因为Hystrix默认的服务超时时间是1秒,这个时间太短了,对响应时间稍微长一点,或者网络速度稍微差一点的服务是不友好的。所以我们要在配置文件application.yml添加Hystrix的服务超时时间:

hystrix:command:default:execution:isolation:thread:timeoutInMilliseconds: 5000

这里我们设置默认的服务超时时间为5秒(5000毫秒)。

下面我们模拟服务崩溃的情况,我们将user服务停止,这样movie去请求user的时候会失败的:

此时我们重新请求“movie/{id}”服务,可以看到返回的正是我们的降级服务findUserByIdFallback返回的Id为0的数据:

我们也可以观察到,浏览器在请求时也没有加载的迹象,我们打断点的时候,可以看到此时服务会在进入findUserById后,直接进findUserByIdFallback方法,而不会再去尝试请求原有服务。

一个简单的配置和演示就到这里,后面的博文会对Hystrix进行进一步的剖析。

参考:《51CTO学院Spring Cloud高级视频》
https://blog.csdn.net/syc000666/article/details/96097567
https://blog.csdn.net/zjl_pcw/article/details/87175077

转载请注明出处:https://blog.csdn.net/acmman/article/details/100523411

【Spring Cloud总结】17.Hystrix简介及简单代码示例相关推荐

  1. Hystrix简介及简单代码示例

    Circuit Breaker:Hystrix Clientshttps://cloud.spring.io/spring-cloud-netflix/multi/multi__circuit_bre ...

  2. Spring Cloud入门教程-Hystrix断路器实现容错和降级

    简介 Spring cloud提供了Hystrix容错库用以在服务不可用时,对配置了断路器的方法实行降级策略,临时调用备用方法.这篇文章将创建一个产品微服务,注册到eureka服务注册中心,然后我们使 ...

  3. 10 在Spring Cloud中使用Hystrix

    Hystrix主要用于保护调用服务的一方,如果被调用的服务发生故障,符合一定条件,就会开启断路器对调用的程序进行隔离. 1.准备测试程序 在进行Spring Cloud整合Hystrix之前,我们先准 ...

  4. 【夯实Spring Cloud】Spring Cloud中使用Hystrix实现断路器原理详解(上)

    本文属于[夯实Spring Cloud]系列文章,该系列旨在用通俗易懂的语言,带大家了解和学习Spring Cloud技术,希望能给读者带来一些干货.系列目录如下: [夯实Spring Cloud]D ...

  5. Spring Cloud(微服务简介)

    一.什么是微服务 通常而言,微服务架构是一种架构模式,或者说是一种架构风格,它提倡将单一的应用程序划分成一组小的服务每个服务运行在独立的进程内,服务之间互相协调,互相配置,为用户提供最终价值.服务之间 ...

  6. Spring Cloud (Eureka,Feign,Hystrix整合)

    Spring Cloud(Eureka,Feign,Hystrix整合) Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代 ...

  7. spring cloud云服务架构 - particle云架构代码结构讲解

    上一篇我们介绍了spring cloud云服务架构 - particle云架构代码结构,简单的按照几个大的部分去构建代码模块,让我们来回顾一下: 第一部分: 针对于普通服务的基础框架封装(entity ...

  8. C#摄像头实现拍照功能的简单代码示例

    C#摄像头实现拍照功能的简单代码示例 2009-11-20  来自:网上整理字体大小:[大中小] ·摘要:这里将介绍一个C#摄像头实现拍照功能的简单代码示例,代码虽然不短,但是基本上实现了相对应的功能 ...

  9. 机器学习简单代码示例

    机器学习简单代码示例 //在gcc-4.7.2下编译通过. //命令行:g++ -Wall -ansi -O2 test.cpp -o test #include <iostream> u ...

最新文章

  1. 浅谈ASP.NET的内部机制(一)
  2. 裸辞后,从Android转战Web前端的学习以及求职之路
  3. php for windows二进制包,PHP5ForWindowsVC9-x865.4.3安装版
  4. Android之error: ‘const struct JNINativeInterface‘ has no member named ‘callVoidMethod‘
  5. 【LeetCode笔记】剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)
  6. 诗与远方:无题(三)
  7. vue cli 对解析的html内容的图片添加样式
  8. 最大似然估计_R初等统计分析(一)——概率分布、最大似然估计
  9. 矩阵运算和一些基本的几何运算
  10. 专属设计师的专业领域导航网站
  11. Mysql之事务与视图
  12. win10多合一原版系统_制作WIN10多合一原版系统工具下载
  13. 计算机桌面ico图标,.ico格式图标制作转换教程及DIY桌面图标的方法
  14. C++:建立一个被称为sroot()的函数,返回其参数的二次方根。重载sroot()3次,让它返回整数、长整数与双精度的二次方根
  15. css3 微信聊天小尖角,用CSS制作聊天框小尖角、气泡效果
  16. vivo手机光环助手下载游戏怎么打不开_“点亮夜色,点亮你”——全新5G自拍手机,vivo S6系列正式发布...
  17. Oracle rman中restore和recover的区别
  18. Java源码:Reference与ReferenceQueue
  19. Firefox(火狐)好用的插件
  20. 通过HFS低成本搭建NAS,并内网穿透实现公网访问 1/2

热门文章

  1. 静态数据/动态数据/使用中数据概念及数据防泄漏 隐私保护
  2. Vue实例的属性及模板渲染
  3. ant design pro vue 动态路由 流程详解
  4. 玩玩Redis系列(八)--redis数据结构及使用场景
  5. 真正的3D桌面!以后的Windows会是这样的?
  6. 易百教程人工智能python修正-人工智能监督学习(回归)
  7. 数据分析里常用的五个统计学概念,你知道几个?
  8. webView网页自适应屏幕
  9. 大数据核心技术与应用实战峰会(下):六专家带你探秘各企业内的大数据实践...
  10. amd 5600g 主机运行ubuntu桌面浏览器崩溃故障初探