【Hystrix技术指南】(5)Command创建和执行实现

创建流程

构建HystrixCommand或者HystrixObservableCommand对象

  • *使用Hystrix的第一步是创建一个HystrixCommand或者HystrixObservableCommand对象来表示你需要发给依赖服务的请求。

若只期望依赖服务每次返回单一的回应,按如下方式构造一个HystrixCommand即可

HystrixCommand command = new HystrixCommand(arg1, arg2);
复制代码

若期望依赖服务返回一个Observable,并应用『Observer』模式监听依赖服务的回应,可按如下方式构造一个HystrixObservableCommand

HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);
复制代码

执行命令

Hystrix 命令提供四种方式(HystrixCommand支持所有四种方式,而HystrixObservableCommand仅支持后两种方式)来执行你包装的请求

  • execute()—— 阻塞,当依赖服务响应(或者抛出异常/超时)时,返回结果
  • queue()—— 返回Future对象,通过该对象异步得到返回结果
  • observe()—— 返回Observable对象,立即发出请求,在依赖服务响应(或者抛出异常/超时)时,通过注册的Subscriber得到返回结果
  • *toObservable()—— 返回Observable对象,但只有在订阅该对象时,才会发出请求,然后在依赖服务响应(或者抛出异常/超时)时,通过注册的Subscriber得到返回结果
K value   = command.execute();
Future     fValue  = command.queue();Observable ohValue = command.observe();Observable ocValue = command.toObservable();
复制代码

内部实现中

  • execute()是同步调用,内部会调用queue().get()方法
  • queue()内部会调用toObservable().toBlocking().toFuture()

HystrixCommand内部均通过一个Observable的实现来执行请求,即使这些命令本来是用来执行同步返回回应这样的简单逻辑。

1. 结果是否有缓存

如果请求结果缓存这个特性被启用,并且缓存命中,则缓存的回应会立即通过一个Observable对象的形式返回。

2. 请求线路是否是开路

  • 当执行一个命令时,Hystrix 会先检查熔断器状态,确定请求线路是否是开路
  • *如果请求线路是开路,Hystrix将不会执行这个命令,而是直接使用『失败回退逻辑』fallback

3. 线程池/请求队列/信号量占满时会发生什么

如果和当前需要执行的命令相关联的线程池和请求队列(或者信号量,如果不使用线程池),Hystrix 将不会执行这个命令,而是直接使用『失败回退逻辑』

使用HystrixObservableCommand.construct()还是HystrixCommand.run()

Hystrix将根据你使用类的不同,内部使用不同的方式来请求依赖服务:

  • HystrixCommand.run()—— 返回回应或者抛出异常
  • *HystrixObservableCommand.construct()—— 返回Observable对象,并在回应到达时通知 observers,或者回调onError方法通知出现异常

若run()或者construct()方法耗时超过了给命令设置的超时阈值,执行请求的线程将抛出TimeoutException( 若命令本身并不在其调用线程内执行,则单独的定时器线程会抛出该异常)。

在这种情况下,Hystrix将会执行失败回退逻辑,并且会忽略最终(若执行命令的线程没有被中断)返回的回应

若命令本身并不抛出异常,并正常返回回应,Hystrix在添加一些日志和监控数据采集之后,直接返回回应。

  • Hystrix 在使用run()方法时,Hystrix内部还是会生成一个Observable对象,并返回单个请求,产生一个onCompleted通知
  • *而在 Hystrix 使用construct()时,会直接返回由construct()产生的Observable对象

计算线路健康度

Hystrix会将请求成功,失败,被拒绝或超时信息报告给熔断器,熔断器维护一些用于统计数据用的计数器。

这些计数器产生的统计数据使得熔断器在特定的时刻,能短路某个依赖服务的后续请求,直到恢复期结束,若恢复期结束根据统计数据熔断器判定线路仍然未恢复健康,熔断器会再次关闭线路。

失败回退逻辑

当命令执行失败时,Hystrix 将会执行失败回退逻辑,失败原因可能是

  1. construct()或run()方法抛出异常HystrixBadRequestException除外
  2. 当线路是开路,导致命令被短路时
  3. 当命令对应的线程池或信号量被占满
  4. 执行操作超时!

回退具体介绍

  • 失败回退逻辑包含了通用的回应信息,这些回应从内存缓存中或者其他固定逻辑中得到,而不应有任何的网络依赖
  • 如果一定要在失败回退逻辑中包含网络请求,必须将这些网络请求包装在另一个HystrixCommand或HystrixObservableCommand中
  • 当使用HystrixCommand时,通过实现HystrixCommand.getFallback()返回失败回退时的回应。
  • 当使用HystrixObservableCommand时,通过实现HystrixObservableCommand.resumeWithFallback()返回 Observable 对象来通知 observers 失败回退时的回应。
  • 若失败回退方法返回回应,Hystrix会将这个回应返回给命令的调用者。
    • 若Hystrix内部调用HystrixCommand.getFallback()时,会产生一个Observable对象,并包装用户实现的getFallback()方法返回的回应;
    • 若 Hystrix内部调用HystrixObservableCommand.resumeWithFallback()时,会将用户实现的resumeWithFallback()返回的Observable对象直接返回。
    • 若你没有实现失败回退方法,或者失败回退方法抛出异常,Hystrix 内部还是会生成一个 Observable对象,但它不会产生任何回应,并通过onError通知立即中止请求
    • Hystrix默认会通过onError通知调用者发生了何种异常。你需要尽量避免失败回退方法执行失败,保持该方法尽可能的简单不易出错
    • 若失败回退方法执行失败,或者用户未提供失败回退方法,Hystrix会根据调用执行命令的方法的不同而产生不同的行为
      • execute()—— 抛出异常
      • queue()—— 成功返回Future对象,但其get()方法被调用时,会抛出异常
      • observe()—— 返回Observable对象,当你订阅它的时候,会立即调用 subscriber 的onError方法中止请求
      • *toObservable()—— 返回Observable对象,当你订阅它的时候,会立即调用 subscriber 的onError方法中止请求

返回正常回应

若命令成功被执行,Hystrix将回应返回给调用方,或者通过Observable的形式返回。根据上述调用命令方式的不同(如第2条所示),Observable对象会进行一些转换:

Observable对象的转化

  • execute()—— 产生一个Future对象,行为同.queue()产生的Future对象一样,接着调用其get()方法,生成由内部产生的Observable对象返回的回应
  • queue()—— 将内部产生的Observable对象转换(Decorator模式)成BlockingObservable对象,以产生并返回Future对象
  • observe()—— 产生Observable对象后,立即订阅(ReplaySubject)以使命令得以执行(异步),返回该Observable对象,当你调用其subscribe方法时,重放产生的回应信息和通知给用户提供的订阅者
  • toObservable()—— 返回Observable对象,你必须调用其subscribe方法,以使命令得以执行

熔断器

下图展示了HystrixCommand或HystrixObservableCommand如何与HystrixCircuitBreaker进行交互,以及HystrixCircuitBreaker的决策逻辑流程,包括熔断器内部计数器如何工作。

熔断器执行逻辑

线路的开路闭路详细逻辑如下:

  1. 假设线路内的容量(请求QPS)达到一定阈值(通过HystrixCommandProperties.circuitBreakerRequestVolumeThreshold()配置)
  2. 同时,假设线路内的错误率达到一定阈值(通过HystrixCommandProperties.circuitBreakerErrorThresholdPercentage()配置)
  3. 熔断器将从『闭路』转换成『开路』
  4. 若此时是『开路』状态,熔断器将短路后续所有经过该熔断器的请求,这些请求直接走『失败回退逻辑』
  5. **经过一定时间(即『休眠窗口』,通过HystrixCommandProperties.circuitBreakerSleepWindowInMilliseconds()配置),后续第一个请求将会被允许通过熔断器(此时熔断器处于『半开』状态)。
  • 若该请求失败,熔断器将又进入『开路』状态,且在休眠窗口内保持此状态;
  • 若该请求成功,熔断器将进入『闭路』状态,回到逻辑1循环往复。

分享资源

资源分享
获取以上资源请访问开源项目 点击跳转

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/32001.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在R中将列表(list)转换为向量(vector)

问题:将列表中的所有元素“展平”,赋值给一个向量 解决方案:使用unlist()函数; 在许多情况下需要向量,例如,baseR中的许多统计函数需要一个向量作为输入,例如,如果iq.score是一个包…

淘宝商品价格查询接口 批量获取商品详情页数据 支持高并发(含调用实例)

接口开发背景 淘宝商品价格查询可以帮助消费者了解和比较不同商品的价格,从而能够作出更明智的购买决策。通过价格查询,消费者可以找到最具性价比的商品,避免被高价或低价的商品误导。此外,价格查询还可以帮助消费者了解市场行情…

JS dom元素和鼠标位置之间的一系列属性快速参考

clientHeight 获取对象的高度,不计算任何边距、边框、滚动条,但包括该对象的补白。 clientLeft 获取 offsetLeft 属性和客户区域的实际左边之间的距离。 clientTop 获取 offsetTop 属性和客户区域的实际顶端之间的距离。 clie…

Sql奇技淫巧之EXIST实现分层过滤

在这样一个场景,我 left join 了很多张表,用这些表的不同列来过滤,看起来非常合理 但是出现的问题是 left join 其中一张或多张表出现了笛卡尔积,且无法消除 FUNCTION fun_get_xxx_helper(v_param_1 VARCHAR2,v_param_2 VARCHAR2…

shell脚本条件测试语句,if,case

shell脚本条件测试语句,if,case 一.条件测试1.1test命令1.2文件测试1.2.1文件测试常见选项 1.3数值比较1.4字符串比较1.5逻辑测试 二.if语句2.1单分支结构2.3多分支 三.case语句 一.条件测试 1.1test命令 测试特定的表达式是否成立,当条件成…

Http常见状态码

一、状态码大类 状态码分类说明1xx响应中——临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它2xx成功——表示请求已经被成功接收,处理已完成3xx重定向——重定向到其它地方:它让客户端再发起一个…

BGP基础实验建邻+宣告实验

实验题目如下: 实验拓扑如下: 实验要求如下: 【1】除R5的5.5.5.0环回外,其他所有的环回均可互相访问 实验思路如下: (1)合理的IP配置 (2)合理的BGP配置 (…

LeetCode 518. 零钱兑换 II(动态规划 完全背包)

题目&#xff1a; 链接&#xff1a;LeetCode 518. 零钱兑换 II 难度&#xff1a;中等 动态规划&#xff1a; dp[i][j] 定义&#xff1a;可选前 i 种硬币的情况下&#xff0c;组成金额 j 的组合数。 初始状态&#xff1a; dp[0][j] 0, 1 < j < amount&#xff08;不选…

SQL | 计算字段

7-创建计算字段 7.1-计算字段 存储在数据库中的数据一般不是我们所需要的字段格式&#xff0c; 需要公司名称&#xff0c;同时也需要公司地址&#xff0c;但是这两个数据存储在不同的列中。 省&#xff0c;市&#xff0c;县和邮政编码存储在不同的列中&#xff0c;但是当我们…

工厂老化设备维护的重要性及如何维护老化设备?

工业领域的老化设备问题日益凸显&#xff0c;对于保持生产稳定和效率至关重要。本文将探讨工厂老化设备维护的重要性&#xff0c;并介绍如何通过PreMaint设备数字化平台实现对老化设备的高效维护&#xff0c;从而确保工厂持续高效运转。 一、工厂老化设备的重要性 随着时间的推…

基于Python爬虫+词云图+情感分析对某东上完美日记的用户评论分析

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

在SPSS中实现数据转置

在使用SPSS开展数据分析的过程中&#xff0c;有时候不可避免需要对数据进行转置处理。 例如Kendall协同系数检验和组内相关系数&#xff08;ICC&#xff09;检验这两种方法都可以检验定量数据的一致性程度&#xff0c;但是这两种方法对数据的要求不同。 组内相关系数&#xf…

layui 集成 ztree异步加载

首先&#xff0c;layui环境搭建&#xff0c;ztree环境引入 ztree的js和css都要引入&#xff0c;我这里暂时用的是core包> 静态&#xff0c;一句话就够了 <!-- 左侧菜单树形组件 --><div class"layui-col-md3"><div class"layui-footer "…

Ajax-概念、Http协议、Ajax请求及其常见问题

Ajax Ajax概念Ajax优缺点HTTP协议请求报文响应报文 Ajax案例准备工作express基本使用创建一个服务器 发送AJAX请求GET请求POST请求JSON响应 Ajax请求出现的问题IE缓存问题Ajax请求超时与网络异常处理Ajax手动取消请求Ajax重复发送请求问题 Ajax概念 AJAX 全称为Asynchronous J…

干货 | 详述 Elasticsearch 向量检索发展史

1. 引言 向量检索已经成为现代搜索和推荐系统的核心组件。 通过将复杂的对象&#xff08;例如文本、图像或声音&#xff09;转换为数值向量&#xff0c;并在多维空间中进行相似性搜索&#xff0c;它能够实现高效的查询匹配和推荐。 图片来自&#xff1a;向量数据库技术鉴赏【上…

安科瑞物联网表在虚拟电厂的应用

安科瑞 崔丽洁 应用场景 一般应用于控制中心 功能 能计量当前组合有功电能&#xff0c;正向有功电能&#xff0c;反向有功电能&#xff0c;正向无功电能&#xff0c;反向无功电能&#xff1b; ADW300支持RS485通讯、LORA通讯、NB、4G及Wifi通讯&#xff1b; 三套时段表,一年可以…

[oeasy]python0081_[趣味拓展]ESC键进化历史_键盘演化过程_ANSI_控制序列_转义序列_CSI

光标位置 回忆上次内容 上次了解了 新的转义模式 \033 逃逸控制字符 escape 这个字符 让字符串 退出标准输出流进行控制信息的设置 可以设置 光标输出的位置 ASR33中的ALT MODE 是 今天的ESC键吗&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#x1f914; 查询文档…

关于APP备案、小程序备案的问题,如何备案?

近日&#xff0c;工信部发布了关于开展移动互联网应用程序备案工作的通知。为落实相关法律法规要求&#xff0c;促进互联网行业规范健康发展&#xff0c;进一步做好移动互联网信息服务管理&#xff0c;现组织开展移动互联网应用程序&#xff08;以下简称 APP&#xff09;备案工…

安灯Andon系统的应用与优势

安灯系统是一款与硬件相结合&#xff0c;实时了解机台与工位状态&#xff0c;让异常的信息得到快速、高效的解决的系统软件&#xff0c;同时记录每次异常报警的种类、响应时间和处理问题用时&#xff0c;提供改善生产管理和人员考核的数据参考&#xff0c;实现透明、快速的生产…

做软件测试,掌握哪些技术才能算作“测试大佬”?

一、过硬的基础能力 其实所有的测试大佬都是从底层基础开始的&#xff0c;随着时间&#xff0c;经验的积累慢慢变成大佬。要想稳扎稳打在测试行业深耕&#xff0c;成为测试大牛&#xff0c;首当其冲的肯定就是拥有过硬的基础&#xff0c;所有的基础都是根基&#xff0c;后期所有…