在微服务架构中,我们将系统拆分成了很多服务单元,各单元的应用间通过服务注册与订阅的方式相互依赖。但由于每个单元都在不同的进程中运行,一来通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服务自身问题出现调用故障或延迟,而这些问题会直接导致调用方的对外服务也出现延迟,若此时调用方的请求不断增加,最后就会因等待出现故障的依赖方响应形成任务积压,最终导致自身服务的瘫痪。

  举个例子,在一个电商网站中,我们可能会将系统拆分成用户、订单、库存、积分、评论等一系列服务单元。当用户创建一个订单的时候,客户端将调用订单服务的创建订单接口,此时创建订单接口又会向库存服务来请求出货(判断是否有足够库存来出货)。此时若库存服务因自身处理逻辑等原因造成相应缓慢,会直接导致创建订单服务的线程被挂起,以等待库存申请服务的响应,在漫长的等待之后用户会因为请求库存失败而得到创建订单失败的结果。如果在高并发情况之下,因这些挂起的线程在等待库存服务的响应而未能释放,使得后续到来的创建订单请求被阻塞,最终导致订单服务也不可用。

  为了解决服务单元之间的高耦合性,以便于在分布式架构中,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。产生了断路器模式,Spring Cloud Hystrix实现了断路器、线程隔离等一系列服务保护功能。

  接下来,我们就从一个简单示例开始对Spring Cloud Hystrix 的学习与使用。

快速入门

  在开始使用Spring Cloud Hystrix实现断路器之前,我们先用上一篇实现的一些内容为基础,构建一个如下图架构所示的服务调用关系。

我们在这里需要启动的工程有:

  1. eureka-server 工程:服务注册中心,端口为1111。
  2. hello-service工程:HELLO-SERVICE的服务单元,两个实例启动端口分别为8081和8082。
  3. ribbon-consume工程:使用Ribbon实现的额服务消费者,端口为8091。

  在未加入断路器之前,当关闭8081的实例后,发送GET请求到http://localhost:8089/ribbon-consumer,当轮询到8081端口的服务时,得到如下输出:

  

下面我们开始引入Spring Cloud Hystrix

  • 在ribbon-consumer工程的pom.xml的dependency节点中引入spring-cloud-started-hystrix依赖:
      <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
  • 在ribbon-consumer工程的主类ConsumerApplication中使用@EnableCircuitBreaker注解开启断路器功能:
 @EnableCircuitBreaker①
@EnableDiscoveryClient
@SpringBootApplication
public class ProvideApplication { @Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ProvideApplication.class, args);
}
}
  • 改造服务消费方式,新增HelloService类,注入RestTemplate实例。然后,将在ConsumerController中对RestTemplate的使用迁移到helloSerice函数中,最后,在helloService函数上增加@HystrixCommand注解来指定回调方法:
 @Service
public class HelloService {
@Autowired
RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "helloFallback")
public String helloService() {
return restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody();
} public String helloFallback() {
return "error";
} }
  • 修改ConsumerController类,注入上面实现的HelloService实例,并在helloConsumer中进行调用:
 @RestController
public class HelloController { @Autowired
HelloService helloService; @RequestMapping(value="/ribbon-consumer",method=RequestMethod.GET)
public String helloConsumer(){
return helloService.helloService();
} }

  下面,我们来验证一下通过断路器实现的服务回调逻辑,重新启动之前关闭的8081端口的HELLO-SERVICE,确保此时服务注册中心、两个HELLO-SERVICE以及RIBBON-CONSUMER均已启动,访问http://localhost:8091/ribbon-consumer可以轮询两个HELLO-SERVICE并返回一些文字信息。此时我们继续断开8081的HELOO-SERVICE,然后访问论寻到8081服务端时,输出内容为error,不再是之前的错误。

至此Hystrix的服务搭建成功!


注释一:可以去掉当前所有注解,使用@SpringCloudApplication注解修饰应用主类

SpringCloud开发学习总结(五)—— 服务容错保护Hystrix的更多相关文章

  1. Spring Cloud(四):服务容错保护 Hystrix【Finchley 版】

    Spring Cloud(四):服务容错保护 Hystrix[Finchley 版]  发表于 2018-04-15 |  更新于 2018-05-07 |  分布式系统中经常会出现某个基础服务不可用 ...

  2. 白话SpringCloud | 第五章:服务容错保护(Hystrix)

    前言 前一章节,我们知道了如何利用RestTemplate+Ribbon和Feign的方式进行服务的调用.在微服务架构中,一个服务可能会调用很多的其他微服务应用,虽然做了多集群部署,但可能还会存在诸如 ...

  3. Spring Cloud (8) 服务容错保护-Hystrix依赖隔离

    依赖隔离 docker使用舱壁模式来实现进程的隔离,使容器与容器之间不会互相影响.而Hystrix则使用该模式实现线程池的隔离,它会为每一个Hystrix命令创建一个独立的线程池,这样就算在某个Hys ...

  4. Spring Cloud (7) 服务容错保护-Hystrix服务降级

    在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以互相调用,在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用.为了保证其高可用,单个服务通常会集群 ...

  5. Spring Cloud (9) 服务容错保护-Hystrix断路器

    断路器 断路器本身是一种开关装置,用于在电路上保护线路过载,当线路中又电路发生短路时,断路器能够及时的切断故障电路,放置发生过载.发热.甚至起火等严重后果. 在分布式架构中,断路器模式的作用也是类似, ...

  6. 服务容错保护hystrix

    灾难性雪崩效应 如何解决灾难性雪崩效应 降级 超时降级.资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据.实现一个 fallback 方法, 当请求后端服务出现异常的时候, 可以使用 ...

  7. spring cloud 服务容错保护 - Hystrix

    1.为什么要断路器 在微服务架构中通常会涉及到多个服务间调用,处于调用链路底层的基础服务故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应.服务雪崩效应是一种因“服务提供 ...

  8. SpringCloud开发学习总结(七)—— 声明式服务调用Feign(一)

    在实践的过程中,我们会发现在微服务架构中实现客户端负载均衡的服务调用技术Spring Cloud Ribbon<SpringCloud开发学习总结(四)—— 客户端负载均衡Ribbon> ...

  9. 《Spring Cloud》学习(三) 容错保护!

    在微服务架构中,我们将系统拆分成了很多服务单元,各单元的应用间互相依赖.由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服务自身间题出现调用故障或延迟,而 ...

随机推荐

  1. httpclient发送get请求

    /** * 获取httpclient的请求url地址 */ public static String getUrl(){ String url = "http://"+map.ge ...

  2. 【Mongodb教程 第十二课 】PHP mongodb 的使用

    mongodb 不用过多的介绍了,NOSQL的一种,是一个面向文档的数据库,以其方便灵活的数据结构,对于开发者来说是比较友好的,同时查询的速度也是比较快的,现在好多网站 开始使用mongodb ,具体 ...

  3. Redis管理key命令

    1 DEL key该命令用于在 key 存在时删除 key. 2 DUMP key 序列化给定 key ,并返回被序列化的值. 3 EXISTS key 检查给定 key 是否存在. 4 EXPIRE ...

  4. asp.net 实现搜索站内搜索功能

    首先有index和search 两个页面 index页面中有textbox1和button1两个控件 双击button1控件添加代码: protected void Button1_Click(obj ...

  5. TPC-H is a Decision Support Benchmark

    TPC-H is a Decision Support Benchmark http://www.dba-oracle.com/t_tpc_benchmarks.htm

  6. jeesite快速开发平台

    兴致勃勃地下载下来准备好好研究一番,安装启动结果报错啦: java.lang.ClassNotFoundException: com.thinkgem.jeesite.modules.sys.list ...

  7. (续)linux SD卡初始化---mmc_sd_init_card函数

    mmc_sd_init_card剩下的关于UHS-I的分支结构. uhs-I的初始化流程图如图: 红线标出的部分是已经做了的事,与上一篇那个流程图是一致的,之后就是if分支中做的事. if分支中的函数 ...

  8. 一步一步学Silverlight 2系列(4):鼠标事件处理

    一步一步学Silverlight 2系列(4):鼠标事件处理   概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言V ...

  9. 并不对劲的字符串专题(二):kmp

    据说这些并不对劲的内容是<信息学奥赛一本通提高篇>的配套练习. 先感叹一句<信息学奥赛一本通提高篇>上对kmp的解释和matrix67的博客相似度99%(还抄错了),莫非mat ...

  10. Ural2089:Experienced coach(二分图匹配)

    Misha trains several ACM teams at the university. He is an experienced coach, and he does not undere ...