1. 回顾

  上文讲解了容错的重要性,以及容错需要实现的功能。

  本文来讲解使用Hystrix实现容错。

2. Hystrix简介

  Hystrix是Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或第三方库,防止级联失败,从而提高系统的可用性与容错性。

  Hystrix主要通过以下几点实现延迟和容错:

  • 包裹请求:使用HystrixCommand(或HystrixObservableCommand)包裹对依赖的调用逻辑,每个命令在独立线程中执行。

    这使用到了设计模式中的“命令模式”。

  • 跳闸机制:当某服务的错误率超过一定阈值时,Hystrix可以自动或者手动跳闸,停止请求该服务一段时间。
  • 资源隔离:Hystrix为每个依赖都维护了一个小型的线程池(或者信号量)。如果该线程池已满,发往该依赖的请求就被立即拒绝,

    而不是排队等候,从而加速失败判定。

  • 监控:Hystrix可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等。
  • 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。回退逻辑可由开发人员自行提供,例如返回一个缺省值。
  • 自我修复:断路器打开一段时间后,会自动进入“半开”状态。断路器打开、关闭、半开的逻辑转换,上文已经详细探讨过,不再赘述。

3. 通用方式整合Hystrix

  > 复制项目 microservice-consumer-movie-ribbon,将 ArtifactId 修改为 microservice-consumer-movie-ribbon-hystrix

  > 添加 hystrix 的依赖

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

  > 在启动类上添加 @EnableCircuitBreaker 或 @EnableHystrix 注解,从而为项目启用断路器支持

package com.itmuch.cloud.microserviceconsumermovieribbonhystrix;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate; @SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
public class MicroserviceConsumerMovieRibbonHystrixApplication { public static void main(String[] args) {
SpringApplication.run(MicroserviceConsumerMovieRibbonHystrixApplication.class, args);
} @Bean
@LoadBalanced // 实现负载均衡
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

  > 修改 MovieController,让其中的findById方法具备容错能力。

package com.itmuch.cloud.microserviceconsumermovieribbonhystrix.controller;

import com.itmuch.cloud.microserviceconsumermovieribbonhystrix.pojo.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; @RestController
public class MovieController { private static final Logger LOGGER = LoggerFactory.getLogger(MovieController.class); @Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient; @HystrixCommand(fallbackMethod = "findByIdFallback")
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://microservice-provider-user/" + id, User.class);
} @GetMapping("/log-instance")
public void logUserInstance() {
ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
// 打印当前选择的是哪个节点
MovieController.LOGGER.info("{}:{}:{}", serviceInstance.getServiceId(), serviceInstance.getHost(),
serviceInstance.getPort());
} public User findByIdFallback(Long id) {
LOGGER.warn("请求异常,执行回退方式");
User user = new User();
user.setId(-1L);
user.setName("默认用户");
return user;
} }

  > 启动项目 microservice-discovery-eureka

  > 启动项目 microservice-provider-user

  > 启动项目 microservice-consumer-movie-ribbon-hystrix

  > 访问 http://localhost:8010/user/1,获得如下结果,说明可正常访问

  > 停止项目 microservice-provider-user

  > 访问 http://localhost:8010/user/1,获得如下结果,说明当用户微服务不可用时,进入了回退方法

  注意:当请求失败、被拒绝、超时或者断路器打开时,都会进入回退方法。但进入回退方法并不意味着断路器已被打开。

4. Hystrix断路器的状态监控与深入理解

  还记得之前已经为项目引入了Spring Boot Actuator 的依赖,该依赖的作用就是监控应用程序的运行状态。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

  断路器的状态也会暴露在Actuator提供的 /actuator/health 端口中,这样就可以直观地了解断路器的状态。

  但是之前使用的是 Actuator 的默认配置。在默认配置中,/actuator/health 端口只能查看系统的状态,不能查看详细信息,

  因此需要对 Actuator进行进一步配置。

  在 application.yml 中添加如下配置

management:
endpoint:
health:
show-details: always

  > 启动项目 microservice-discovery-eureka

  > 启动项目 microservice-consumer-movie-ribbon-hystrix

  > 访问 http://localhost:8010/user/1,结果如下,说明已执行了回退逻辑,返回了默认用户。

  > 访问 http://localhost:8010/actuator/health,结果如下,此时Hystrix的状态依然是 UP,这是因为我们的失败率还没有达到阈值

    (默认是5秒返回20次失败)

  > 持续快速的访问 http://localhost:8010/user/1,然后访问 http://localhost:8010/actuator/health,此时结果如下

  注意:由上面的测试可以发现——执行回退逻辑并不代表断路器已经打开。请求失败、超时、被拒绝以及断路器打开时都会执行回退逻辑。

5. Hystrix线程隔离策略与传播上下文

  先来阅读一下Hystrix官方Wiki(https://github.com/Netflix/Hystrix/wiki/Configuration#execution.isolation.strategy

  执行

    以下属性控制 HystrixCommand.run() 是如何运行的

  execution.isolation.strategy

    这个属性决定了 HystrixCommand.run() 以哪种隔离策略去执行,下面两种选择中的一个:

    • THREAD(线程隔离):它将在单独的线程上执行,并发请求受线程池中的线程数量的限制。
    • SEMAPHORE(信号量隔离):它将在调用线程上执行,开销相对较小,并发请求收到信号量个数的限制。

  Thread or Semaphore

    默认并且推荐的设置是,运行 HystrixCommand 使用线程隔离(THREAD)HystrixObservableCommand 使用信号量隔离(SEMAPHORE)

    在线程中执行命令有一个除网络超时以外的额外保护层。

    一般来说,只有当调用负载非常高时(每个实例每秒调用数百次)才需要对 HystrixCommand 使用信号量隔离,因为这种场景下

    使用单独线程开销太高,这通常只适用于非网络调用。

  

  了解了Hystrix的隔离策略后,再来看一下 Spring Cloud 官方的文档(http://cloud.spring.io/spring-cloud-static/Finchley.M8/single/spring-cloud.html#_propagating_the_security_context_or_using_spring_scopes

  如果你想传播线程本地的上下文到 @HystrixCommand,默认声明将不会工作,因为它会在线程池中执行命令(在超时的情况下)。

  你可以使用一些配置,让 Hystrix 使用相同的线程,或者直接在注解中让 Hystrix 使用不同的隔离策略。例如:

@HystrixCommand(fallbackMethod = "stubMyService",
commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE")
}
)
...

  这也适用于使用 @SessionScope 和 @RequestSession 的情况。你会知道什么时候需要这么做,因为会发生一个运行时异常,

  说它找不到作用域上下文(scoped context)。

  你还可以将 hystrix.shareSecurityContext 属性设置为 true,这样将会自动配置一个 Hystrix 并发策略插件的 hook,这个hook会

  将 SecurityContext 从主线程传输到 Hystrix 的命令。因为 Hystrix 不允许注册多个 Hystrix 策略,所以可以声明 HystrixConcurrencyStrategy

  为一个Spring bean来实现扩展。Spring Cloud会在Spring的上下文中查找你的实现,并将其包装在自己的插件中。

  把Spring Cloud 和 Hystrix 的文档对照阅读,可以帮助理解相关概念。

  • Hystrix的隔离策略有THREAD和SEMAPHORE两种,默认是THREAD。
  • 正常情况下,保持默认即可。
  • 如果发生找不到上下文的运行时异常,可考虑将隔离策略设置为SEMAPHORE。

6. 总结

  本文讲解了Hystrix的整合,对Hystrix断路器的理解及监控,还有Hystrix的隔离策略与传播上下文等。

  下文将讲解Feign使用Hystrix。敬请期待~~~

7. 参考

  周立 --- 《Spring Cloud与Docker微服务架构与实战》

SpringCloud系列十五:使用Hystrix实现容错的更多相关文章

  1. SpringCloud系列十四:实现容错的手段

    1. 回顾 前面已用Eureka实现了微服务的注册与发现,Ribbon实现了客户端侧的负载均衡,Feign实现了声明式的API调用. 2. 实现容错的手段 如果服务提供者响应非常慢,那么消费者对提供者 ...

  2. 跟我学SpringCloud | 第十五篇:微服务利剑之APM平台(一)Skywalking

    目录 SpringCloud系列教程 | 第十五篇:微服务利剑之APM平台(一)Skywalking 1. Skywalking概述 2. Skywalking主要功能 3. Skywalking主要 ...

  3. 学习ASP.NET Core Razor 编程系列十五——文件上传功能(三)

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  4. 聊聊MySQL的加锁规则《死磕MySQL系列 十五》

    大家好,我是咔咔 不期速成,日拱一卒 本期来聊聊MySQL的加锁规则,知道这些规则后可以判断SQL语句的加锁范围,同时也可以写出更好的SQL语句,防止幻读问题的产生,在能力范围内最大程度的提升MySQ ...

  5. SpringCloud系列十六:Feign使用Hystrix

    1. 回顾 上文讲解了使用注解@HystrixCommand的fallbackMethod属性实现回退.然而,Feign是以接口形式工作的, 它没有方法体,前文讲解的方式显然不适用与Feign. 事实 ...

  6. 【Qt编程】基于Qt的词典开发系列<十五>html特殊字符及正则表达式

    1.html特殊字符的显示 我们知道html语言和C语言一样也有一些特殊字符,它们是不能正常显示的,必须经过转义,在网上可以查到如何显示这些字符,如下图所示: 上图给了最常用的特殊字符的显示,下面我们 ...

  7. SSE图像算法优化系列十五:YUV/XYZ和RGB空间相互转化的极速实现(此后老板不用再担心算法转到其他空间通道的耗时了)。

    在颜色空间系列1: RGB和CIEXYZ颜色空间的转换及相关优化和颜色空间系列3: RGB和YUV颜色空间的转换及优化算法两篇文章中我们给出了两种不同的颜色空间的相互转换之间的快速算法的实现代码,但是 ...

  8. SpringCloud系列十二:SpringCloudSleuth(SpringCloudSleuth 简介、SpringCloudSleuth 基本配置、数据采集)

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringCloudSleuth 2.具体内容 Sleuth 是一种提供的跟踪服务,也就是说利用 sleuth 技术 ...

  9. SpringCloud系列十:SpringCloudConfig 高级配置(密钥加密处理(JCE)、KeyStore 加密处理、SpringCloudConfig 高可用机制、SpringCloudBus 服务总线)

    1.概念:SpringCloudConfig 高级配置 2.具体内容 在 SpringCloudConfig 之中考虑到所有配置文件都暴露在远程仓库之中的安全性问题,所以提供有安全访问的处理机制,这样 ...

随机推荐

  1. 51nod 子序列的个数(动态规划)

    子序列的个数 给定一个正整数序列,序列中元素的个数和元素值大小都不超过105, 求其所有子序列的个数.注意相同的只算一次:例如 {1,2,1}有子序列{1} {2} {1,2} {2,1}和{1,2, ...

  2. RabbitMQ (一) 简介和基本概念

    原文:https://blog.csdn.net/vbirdbest/article/details/78577043 一.简介 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序 ...

  3. [BZOJ 1212] L语言

    Link: BZOJ 1212 传送门 Solution: 看到字符串的多模式匹配,正解一般就是Trie树/AC自动机 此题由于每个模式串长度都很小,于是直接在Trie树上暴力就行了 先把所有模式串建 ...

  4. [TC-HouseProtection]House Protection

    题目大意: 一个平面直角坐标系中有给定的$n(n\le50)$个红点和$m(m\le50)$个蓝点,每个点可以选择画一个半径为$r$(所有的$r$相同)的圆或不画.圆的半径上限为$R(R\le1000 ...

  5. 如何在debug模式下,使用正式的签名文件

    有两种方式(在集成第三方库的使用 使用的非常多)  签名配置信息 一是直接按F4,在项目结构面板中进行设置,只要操作两个两个选项卡就好了,signing(生成配置信息)和build types(打包类 ...

  6. C# 使用 System.Web.Script.Serialization 解析 JSON

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器解析和生成.它基于JavaScript Programming Langu ...

  7. sql-server-on-linux-how-i-think-they-did-it : Anthony Nocentino's Blog

    http://www.sqlservercentral.com/blogs/anthony-nocentinos-blog/2016/11/21/sql-server-on-linux-how-i-t ...

  8. Debian、Ubuntu 源列表说明

    转载:http://forum.ubuntu.org.cn/viewtopic.php?t=366506 概貌: 源列表主文件为 /etc/apt/sources.list,另兼取 /etc/apt/ ...

  9. PHP中使用XMLRPC

    PHP中简单使用XMLRPC,服务器端和客户端都为PHP代码实现. 这里使用的XML-RPC完整包括client和server的XML-RPC实现. 客户端和服务器端分别由 xmlrpc_client ...

  10. 使用x64dbg分析微信聊天函数并实现发信息

    1.引言 我们知道微信现在不光在手机上很常用,在电脑也是非常常用的,尤其是使用微信联系客户和维护群的人,那这个时候每天都会定期发送一些信息,如果人工操作会很累,所以自动化工具是王道,本节就使用x64d ...