文档章节

跟我学Spring Cloud(Finchley版)-13-通用方式使用Hystrix

周立_ITMuch
 周立_ITMuch
发布于 01/19 09:27
字数 1228
阅读 28
收藏 5

本节详细讲解使用Hystrix的通用方式。

简介

Hystrix是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。Hystrix主要通过以下几点实现延迟和容错。

  • 包裹请求

使用HystrixCommand(或HystrixObservableCommand)包裹对依赖的调用逻辑,每个命令在独立线程中执行。这使用到了设计模式中的“命令模式”。

  • 跳闸机制

当某服务的错误率超过一定阈值时,Hystrix可以自动或者手动跳闸,停止请求该服务一段时间。

  • 资源隔离

Hystrix为每个依赖都维护了一个小型的线程池(或者信号量)。如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加速失败判定。

  • 监控

Hystrix可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等。

  • 回退机制

当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。回退逻辑可由开发人员自行提供,例如返回一个缺省值。

  • 自我修复

断路器打开一段时间后,会自动进入“半开”状态。断路器打开、关闭、半开的逻辑转换,前面我们已经详细探讨过了,不再赘述。

通用方式使用Hystrix

服务降级

  • 加依赖:

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
  • 加注解:在启动类上添加@EnableCircuitBreaker 注解。

  • 使用:

    @HystrixCommand(fallbackMethod = "findByIdFallback")
    @GetMapping("/users/{id}")
    public User findById(@PathVariable Long id) {
      // 这里用到了RestTemplate的占位符能力
      User user = this.restTemplate.getForObject(
        "http://microservice-provider-user/users/{id}",
        User.class,
        id
      );
      // ...电影微服务的业务...
      return user;
    }
    
    public User findByIdFallback(Long id) {
      return new User(id, "默认用户", "默认用户", 0, new BigDecimal(1));
    }
    

    由代码可知,只需使用@HystrixCommand 注解,就可保护该API。这里的”保护“,其实带有三层含义——”超时机制“、”仓壁模式“、”断路器“!如果您不了解这些是什么,或者想要探寻其中原理,可详见:跟我学Spring Cloud(Finchley版)-12-微服务容错三板斧

TIPS

  • 本例使用了fallbackMethod 属性,指定了一个降级方法,如不指定,Hystrix会有一个默认的降级方案,那就是抛异常,哈哈哈。

  • **如何知道断路器打开还是关闭呢?**还记得健康检查吗?只需访问应用的/actuator/health 端点,即可查看!断路器的状态——当然,你必须添加如下配置:

    management:
      endpoint:
        health:
          show-details: always
    

    如果您对这部分知识有遗忘,可前往跟我学Spring Cloud(Finchley版)-03-监控:强大的Spring Boot Actuator 简单复习一下。

测试

  • 启动microservice-discovery-eureka

  • 启动microservice-provider-user

  • 启动microservice-consumer-movie-ribbon-hystrix-common

  • 访问http://localhost:8010/movies/users/1 ,能正常返回结果

  • 关闭microservice-provider-user ,再次访问http://localhost:8010/movies/users/1 ,可返回类似如下结果,说明当服务提供者时,服务消费者进入了回退方法

    {"id":1,"username":"默认用户","name":"默认用户","age":0,"balance":1}
    
  • 访问http://localhost:8010/actuator/health ,可获得类似如下结果:

    {
    	"status": "UP",
    	"details": {
    		"diskSpace": ...,
    		"refreshScope": ...,
    		"discoveryComposite": ...,
    		"hystrix": {
    			"status": "UP"
    		}
    	}
    }
    

    由结果不难发现,此时断路器并未打开!这是为什么呢? 原因是:此时只请求了一次,没有达到Hystrix的阈值——Hystrix设计来保护高并发应用的,它要求10秒(可用hystrix.command.default.metrics.rollingStats.timeInMilliseconds 自定义)以内API错误次数超过20次(用circuitBreaker.requestVolumeThreshold 自定义),此时才可能触发断路器。

  • 持续不断地访问http://localhost:8010/movies/users/1 多次(至少20次)

  • 再次访问http://localhost:8010/actuator/health ,可获得类似如下结果:

    {
    	"status": "UP",
    	"details": {
    		"diskSpace": ...,
    		"refreshScope": ...,
    		"discoveryComposite": ...,
    		"hystrix": {
    			"status": "CIRCUIT_OPEN",
    			"details": {
    				"openCircuitBreakers": ["MovieController::findById"]
    			}
    		}
    	}
    }
    

    由结果可知,此时断路器已经打开,并且列出了是哪个API的断路器被打开了。

获得造成fallback的原因

在实际项目中,很可能需要获得造成fallback的原因,此时可将代码修改为如下:

@HystrixCommand(fallbackMethod = "findByIdFallback")
@GetMapping("/users/{id}")
public User findById(@PathVariable Long id) {
  // 这里用到了RestTemplate的占位符能力
  User user = this.restTemplate.getForObject(
    "http://microservice-provider-user/users/{id}",
    User.class,
    id
  );
  // ...电影微服务的业务...
  return user;
}

public User findByIdFallback(Long id, Throwable throwable) {
  log.error("进入回退方法", throwable);
  return new User(id, "默认用户", "默认用户", 0, new BigDecimal(1));
}

配套代码

本文首发

http://www.itmuch.com/spring-cloud/finchley-13/

干货分享

全是干货

© 著作权归作者所有

共有 人打赏支持
周立_ITMuch
粉丝 141
博文 94
码字总数 93996
作品 1
南京
私信 提问
跟我学Spring Cloud(Finchley版)-18-Zuul深入

本节探讨Zuul的高级特性。 TIPS: 笔者已经写过很多Zuul相关的文章,对于已经写过的内容,就不再啰嗦一遍了,直接贴地址吧。 过滤器详解 过滤器是Zuul的核心,Zuul大多功能都是基于过滤器实现...

周立_ITMuch
01/29
0
0
跟我学Spring Cloud(Finchley版)-11-Feign常见问题总结

本文总结Feign常见问题及解决方案。 一、FeignClient接口如使用 ,必须指定value属性 代码示例: 其中的 中的”id”,也就是value属性,必须指定,不能省略。 二、构造多参数请求 详见:如何...

周立_ITMuch
01/16
0
0
史上最简单的 SpringCloud 教程 | 终章

版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接 ,博主地址:http://blog.csdn.net/forezp。 https://blog.csdn.net/forezp/article/details/70148833 转载请标明出处...

方志朋
2017/04/12
0
0
跟我学Spring Cloud(Finchley版)-10-Feign深入

上一节( 跟我学Spring Cloud(Finchley版)-09-Feign )讲了Feign的入门姿势并深入对比了RestTemplate,本节来深入探讨Feign的高级特性。总的来说,Feign是一个相对简单的组件,但细节还是比...

周立_ITMuch
01/14
0
0
跟我学Spring Cloud(Finchley版)-14-Feign使用Hystrix

Feign默认已经整合了Hystrix,本节详细探讨Feign使用Hystrix的具体细节。 服务降级 加配置,默认Feign是不启用Hystrix的,需要添加如下配置启用Hystrix,这样所有的Feign Client都会受到Hys...

周立_ITMuch
01/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

12_第一个Flutter程序

使用 package 在这一步中,你将开始使用一个名为 english_words 的开源软件包,其中包含数千个最常用的英文单词以及一些实用功能。 你可以 在 pub.dartlang.org 上找到 english_words 软件包...

口十耳
10分钟前
0
0
指明方向与趋势!2019开发者技能报告出炉!!!

近日国外开发者平台 HankerRank 发布了 2019 年开发者技能调查报告( https://research.hackerrank.com/developer-skills/2019 ),该报告根据对71,281开发者的调查得出。 2018 年最受欢迎的...

阿里云官方博客
12分钟前
0
0
【Maven冷知识】Compiler插件

很多同学在pom的配置中都喜欢加上这样一段配置信息: 从配置信息上看,这是maven对Java源代码进行的编译配置,采用了Java 7 进行编译,但是为什么要加上这段配置呢?不加有没有什么影响?很多...

算法与编程之美
15分钟前
0
0
磊哥测评之数据库SaaS篇:腾讯云控制台、DMC和小程序

本文由云+社区发表 作者:腾讯云数据库 随着云计算和数据库技术的发展,数据库正在变得越来越强大。数据库的性能如处理速度、对高并发的支持在节节攀升,同时分布式、实时的数据分析、兼容主...

腾讯云加社区
17分钟前
0
0
Visual Studio系列教程:使用XAML工具创建用户界面(二)

Visual Studio是一款完备的工具和服务,可帮助您为Microsoft平台和其他平台创建各种各样的应用程序。在本系列教程中将介绍如何为图像编辑创建基本的用户界面,有任何建议或提示请在下方评论区...

ymy_666666
19分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部