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

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

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

    JavaScript 是脚本语言 JavaScript 是一种轻量级的编程语言. JavaScript 是可插入 HTML 页面的编程代码. JavaScript 插入 HTML 页面后,可由全部的现 ...

  2. Effective C++ Item 27 少做转型操作

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie todo Item34 旧式转型 (T) expression 或 T (expressio ...

  3. 非计算机专业的伟伯是怎样拿到阿里Offer的。求职励志!!!

    写在前面: 2015 年 7 月初.參加阿里巴巴校招内推, 8 月 15 日拿到研发project师 JAVA 的 offer .我的专业并不是计算机,也没有在互联网公司实习过,仅仅有一些学习和面试心 ...

  4. Binder系列8—如何使用Binder(转)

    一.Native层Binder 源码结构: ClientDemo.cpp: 客户端程序 ServerDemo.cpp:服务端程序 IMyService.h:自定义的MyService服务的头文件 IM ...

  5. soapUI系列之—-03 Groovy脚本常用方法2

    ------Groovy脚本常用方法 1.解析Json数据脚本 //groovy读取json的方式很简单,re.body.businessinfo.c2rate读取c2rate对应的值 import ...

  6. oracle 10g 实例用localhost无法访问的处理

    我在笔记本上安装了一个Oracle10g,安装好了之后,查看E:\oracle\product\10.2.0\db_1\network\ADMIN\tnsnames.ora文件,发现SID对应的IP地 ...

  7. MongoDB数据库的初识

    1,MongoDB是基于分布式文件存储的数据库,有c++语言编写,旨在为WEB应用提供可扩展的高效性能数据存储解决方案. MongoDB是一个介于关系型数据库和非关系数据库之间的产品,是非关系数据库当 ...

  8. 关于数论【polya计数法】

    可以预见数论推公式是有多么蛋疼. 让我简明扼要的讲讲吧(多都说不出来,毕竟才做了两道题)其实呢,这个算法应该归入群论,有个有用的东西:置换群,它表示一个集合包括很多的置换.先讲讲置换吧:↓(这是个置换 ...

  9. create database 默认utf-8

    CREATE DATABASE IF NOT EXISTS dbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci; 这是sql语句 CREATE TA ...

  10. ZOJ - 1610 Count the Colors(线段树区间更新,单点查询)

    1.给了每条线段的颜色,存在颜色覆盖,求表面上能够看到的颜色种类以及每种颜色的段数. 2.线段树区间更新,单点查询. 但是有点细节,比如: 输入: 2 0 1 1 2 3 1 输出: 1 2 这种情况 ...