spring cloud 入门系列四:使用Hystrix 实现断路器进行服务容错保护「建议收藏」

在微服务中,我们将系统拆分为很多个服务单元,各单元之间通过服务注册和订阅消费的方式进行相互依赖。但是如果有一些服务出现问题了会怎么样?比如说有三个服务(ABC),A调用B,B调用C。由于网络延迟或C

大家好,又见面了,我是全栈君。

在微服务中,我们将系统拆分为很多个服务单元,各单元之间通过服务注册和订阅消费的方式进行相互依赖。但是如果有一些服务出现问题了会怎么样?

比如说有三个服务(ABC),A调用B,B调用C。由于网络延迟或C本身代码有问题导致B迟迟得不到回应,这样B调用C的请求就会被挂起,等待。

在高并发的访问的情况下,这些挂起的线程得不到释放,使后续的请求阻塞,最终导致B也挂掉了。依次类推,A可能也会挂掉,进而使整个系统全部崩溃。

为了解决整个问题,Spring Cloud 使用Hystrix进行服务容错保护,包括断路器、线程隔离等一系列的保护功能,今天我们就来看下如何通过Hystrix实现断路器。

一、什么是Spring Cloud Hystrix?什么是断路器?

Spring Cloud Hystrix是基于Netflix的开源框架Hystrix实现的,其目的是为了通过控制那些访问远程系统、服务和第三方的节点,从而对延迟和故障提供强大的容错能力。

断路器类似于我们家里面强电箱里面用到的漏电断路保护器,当服务单元出现故障(类似于电器发生短路),通过断路器的故障监控功能(类似于保险丝),向调用方返回一个错误响应,避免长时间等待,从而避免故障蔓延到整个系统。

二、没有断路器的情况下,页面展示

还记得我们前面写的spring cloud 入门系列二:使用Eureka 进行服务治理里面的三个服务(eureka/hello-service/hello-consumer)吗?我们基于这个进行实验。

  1. 启动eureka服务注册中心,端口号1111
  2. 启动hello-service服务提供者,这里我们启动两个服务,端口号分别为9090,9091
  3. 启动hello-consumer服务消费者,端口号为9999;这个时候我们多次访问http://localhost:9999/hello-consumer是没有问题的
  4. 将hello-service端口号为9091的服务关掉,再去多次访问http://localhost:9999/hello-consumer,报错了spring cloud 入门系列四:使用Hystrix 实现断路器进行服务容错保护「建议收藏」

    PS:这里说明下,为什么要多次访问,是因为我们通过ribbon实现了负载均衡,访问http://localhost:9999/hello-consumer的时候,会轮询访问hello-service的两个服务,当访问到端口号是9091的服务时才报错,访问9090的服务就不会有问题。

三、断路器代码实现

接下来我们看下如何进行代码实现,我们不去修改服务注册中心和服务提供者,只需要修改服务消费者hello-consumer

  1. 修改POM文件,引入Hystrix依赖
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sam</groupId> <artifactId>hello-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <properties> <javaVersion>1.8</javaVersion> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 引入eureka 客户端依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- 引入ribbon 依赖 ,用来实现负载均衡,我们这里只是使用先不作其他介绍 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <!-- 引入hystrix 依赖 ,用来实现服务容错保护--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> </dependencies> </project>

  2. 修改启动类,追加注解@EnableCircuitBreaker,开启断路器
    @EnableDiscoveryClient @SpringBootApplication @EnableCircuitBreaker public class ConsumerApp { //@Bean 应用在方法上,用来将方法返回值设为为bean  @Bean @LoadBalanced //@LoadBalanced实现负载均衡 public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerApp.class, args); } }

    这个时候你会发现,这个启动类加了三个注解,这个是不是很麻烦?没关系,我们可以使用注解@SpringCloudApplication

    @SpringCloudApplication public class ConsumerApp { //@Bean 应用在方法上,用来将方法返回值设为为bean  @Bean @LoadBalanced //@LoadBalanced实现负载均衡 public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerApp.class, args); } }

    @SpringCloudApplication = @EnableDiscoveryClient +@SpringBootApplication+@EnableCircuitBreaker,从源码就能看出来:

    @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication { }

  3. 追加service
    @Service public class ConsumerService { @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "errorMsg") public String consumer() { // 调用hello-service服务,注意这里用的是服务名,而不是具体的ip+port restTemplate.getForObject("http://hello-service/hello", String.class); return "hello consumer finish !!!"; } public String errorMsg() { return "error!!!"; } }

    我们把原来controller里面的调用RestTemplate的实现放到service里面,并且通过@HystrixCommand来指定回调方法,当出现错误时调用该方法。

  4. 修改controller
    /** *这里不再直接调用restTemplate, *而是通过调用service进行实现 * */ @RestController public class ConsumerController { @Autowired // RestTemplate restTemplate;  ConsumerService service; @RequestMapping("/hello-consumer") public String helloConsumer() { // //调用hello-service服务,注意这里用的是服务名,而不是具体的ip+port // restTemplate.getForObject("http://hello-service/hello", String.class);  return service.consumer(); } }

  5. 测试,多次访问,当报错的时候,会显示如下内容

    spring cloud 入门系列四:使用Hystrix 实现断路器进行服务容错保护「建议收藏」

     

大功告成!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/120907.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 二分查找判定树(二分查找树平均查找长度)

    如果data[0]等于一组数据中最小的,那么就会增加查找的时间复杂度。平衡二叉树(追求极致的平衡),现实需求很难满足,红黑数孕育而生

  • 迅雷磁力bt链接下载器_种子搜索

    迅雷磁力bt链接下载器_种子搜索种子文件目录:C:\Users\jifeng\AppData\Local\Temp\magnetex

  • 安装VMtool_虚拟机没有安装VMware Tools

    安装VMtool_虚拟机没有安装VMware Tools安装VMTOOL工具1.VMtoolsVMtools顾名思义就是Vmware的一组工具。主要用于虚拟主机显示优化与调整,另外还可以方便虚拟主机与本机的交互,如允许共享文件夹,甚至可以直接从本机向虚拟主机拖放文件、鼠标无缝切换、显示分辨率调整等,十分实用。2.先启动系统3.安装4.将安装包复制到桌面5.解压压缩包tar-zxvf*.tar.gz6.进入解压文件运行./vmware-install.pl7.安装完成选择yes,遇到选项回车。安装完成reboot。..

  • Dialog中使用Printf

    Dialog中使用Printf

  • JAVA中的数组插入与删除指定元素

    JAVA中的数组插入与删除指定元素今天学了Java的数组,写了数组的插入和删除,本人小白,写给不会的小白看,大神请忽略,有错请大家指出来;/**给数组指定位置数组的插入*/importjava.util.*;publicclassArrayInsert{publicstaticvoidmain(String[]args){System.out.println(“请用键

  • 需求规格说明书模板

    需求规格说明书模板需求规格说明阐述一个软件系统必须提供的功能和性能以及它所要考虑的限制条件,它不仅是系统测试和用户文档的基础,也是所有子系列项目规划、设计和编码的基础。它应该尽可能完整地描述系统预期的外部行为和用户可视化行为。除了设计和实现上的限制,软件需求规格说明不应该包括设计、构造、测试或工程管理的细节。  1)采用软件需求规格说明模版:采用需求规格说明书模板在你的组织中要为编写软…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号