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

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

  为了解决服务单元之间的高耦合性,以便于在分布式架构中,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。产生了断路器模式,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. ADO.NET(OleDb)读取Excel表格时的一个BUG

    如果我们有例如以下一个Excel表格:    如今要使用C#程序读取其内容: using System;  using System.Data.OleDb;    namespace Skyiv.Be ...

  2. 同步定制 Unity团队 程序的C#文件模板

    孙广东   2015.7.30 就是把程序制定好的模板(不论什么人能够更改并同步git)放到,unity项目的Editor 目录下, 当程序新建一个C#脚本后就是这个模板了. "81-C# ...

  3. Web开发从零单排之一:在新浪云平台SAE上开发一个html5电子喜帖

    需求描述: 本人大婚将至,女朋友说“现在都流行在微信上发电子请帖了,你不是技(cheng)术(xu)宅(yuan)嘛,不会连这个都搞不定吧” 本人嘴上说这等小事何足挂齿,但心里还是七上八下的,虽然自认 ...

  4. Ioc 器管理的应用程序设计,前奏:容器属于哪里? 控制容器的反转和依赖注入模式

    Ioc 器管理的应用程序设计,前奏:容器属于哪里?   我将讨论一些我认为应该应用于“容器管理”应用程序设计的原则. 模式1:服务字典 字典或关联数组是我们在软件工程中学到的第一个构造. 很容易看到使 ...

  5. POJ训练计划2299_Ultra-QuickSort(线段树/单点更新)

    解题报告 题意: 求逆序数. 思路: 线段树离散化处理. #include <algorithm> #include <iostream> #include <cstri ...

  6. MySQL InnoDB类型数据库的恢复

     MySQL的数据库文件直接复制便可以使用,但是那是指“MyISAM”类型的表. 而使用MySQL-Front直接创建表,默认是“InnoDB”类型,这种类型的一个表在磁盘上只对应一个“*.frm”文 ...

  7. react-grid-layout

    一个好用的拖拽.自适应布局 react 插件 基本使用: // 显示全部 chart 内容区域 import React,{PureComponent} from 'react'; import {R ...

  8. oracle sql 超长报ORA-01460错误

    程序查找数据的时候报错了: ORA-01460: 转换请求无法实施或不合理 这是什么鬼?不合理你就提嘛,报错干什么. 程序原本好好的,现在突然报错了.数据库并没有什么更改. 后来猜测是因为执行的SQL ...

  9. iOS开发——高级篇——iOS开发之网络安全密码学

    一.非对称加密 - RSA : + 公钥加密,私钥解密: + 私钥加密,公钥解密: + 只能通过因式分解来破解 二.对称加密 - DES - 3DES - AES (高级密码标准,美国国家安全局使用, ...

  10. Class.forName() 详解

    主要功能 Class.forName(xxx.xx.xx)返回的是一个类 Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类, 也就是说JVM会执行该类的静态代码段 ...