Java中间件-Hystrix
发布时间:2025-05-25 01:37:53 发布人:远客网络
一、Java中间件-Hystrix
1、Java中间件Hystrix是一个用于处理分布式系统中依赖服务延迟和故障的组件。以下是关于Hystrix的详细解答:
2、综上所述,Java中间件Hystrix在分布式系统中扮演着重要角色,通过一系列机制保护系统免受依赖服务故障的影响,提高了系统的稳定性和可用性。然而,随着微服务架构的不断演进,也需要关注其替代方案的发展。
二、Sentinel与Hystrix的区别
Sentinel 是阿里中间件团队研发的面向分布式服务架构的轻量级高可用流量控制组件,最近正式开源。Sentinel主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。大家可能会问:Sentinel和之前常用的熔断降级库 Netflix Hystrix有什么异同呢?本文将从多个角度对 Sentinel和 Hystrix进行对比,帮助大家进行技术选型。
Hystrix的关注点在于以隔离和熔断为主的容错机制,超时或者熔断的调用会快速失败,并可以提供fallback机制,而Sentinel的侧重点在与:
可以看到两者解决的问题还是有比较大的不同的,下面我们来分别对比一下
Hystrix的资源模型设计上采用了命令模式,将对外部资源的调用和 fallback逻辑封装成一个命令对象(HystrixCommand / HystrixObservableCommand),其底层的执行是基于 RxJava实现的。每个 Command创建时都要指定 commandKey和 groupKey(用于区分资源)以及对应的隔离策略(线程池隔离 or信号量隔离)。线程池隔离模式下需要配置线程池对应的参数(线程池名称、容量、排队超时等),然后 Command就会在指定的线程池按照指定的容错策略执行;信号量隔离模式下需要配置最大并发数,执行 Command时 Hystrix就会限制其并发调用。
Sentinel的设计则更为简单。相比 Hystrix Command强依赖隔离规则,Sentinel的资源定义与规则配置的耦合度更低。Hystrix的 Command强依赖于隔离规则配置的原因是隔离规则会直接影响 Command的执行。在执行的时候 Hystrix会解析 Command的隔离规则来创建 RxJava Scheduler并在其上调度执行,若是线程池模式则 Scheduler底层的线程池为配置的线程池,若是信号量模式则简单包装成当前线程执行的 Scheduler。而 Sentinel并不指定执行模型,也不关注应用是如何执行的。Sentinel的原则非常简单:根据对应资源配置的规则来为资源执行相应的限流/降级/负载保护策略。在 Sentinel中资源定义和规则配置是分离的。用户先通过 Sentinel API给对应的业务逻辑定义资源(埋点),然后可以在需要的时候配置规则。埋点方式有两种:
try-catch方式(通过 SphU.entry(...)),用户在 catch块中执行异常处理/ fallback
if-else方式(通过 SphO.entry(...)),当返回 false时执行异常处理/ fallback
Sentinel提供多样化的规则配置方式。除了直接通过 loadRules API将规则注册到内存态之外,用户还可以注册各种外部数据源来提供动态的规则。用户可以根据系统当前的实时情况去动态地变更规则配置,数据源会将变更推送至 Sentinel并即时生效。
隔离是 Hystrix的核心功能之一。Hystrix提供两种隔离策略:线程池隔离(Bulkhead Pattern)和信号量隔离,其中最推荐也是最常用的是线程池隔离。Hystrix的线程池隔离针对不同的资源分别创建不同的线程池,不同服务调用都发生在不同的线程池中,在线程池排队、超时等阻塞情况时可以快速失败,并可以提供 fallback机制。线程池隔离的好处是隔离度比较高,可以针对某个资源的线程池去进行处理而不影响其它资源,但是代价就是线程上下文切换的 overhead比较大,特别是对低延时的调用有比较大的影响。
但是,实际情况下,线程池隔离并没有带来非常多的好处。首先就是过多的线程池会非常影响性能。考虑这样一个场景,在 Tomcat之类的 Servlet容器使用 Hystrix,本身 Tomcat自身的线程数目就非常多了(可能到几十或一百多),如果加上 Hystrix为各个资源创建的线程池,总共线程数目会非常多(几百个线程),这样上下文切换会有非常大的损耗。另外,线程池模式比较彻底的隔离性使得 Hystrix可以针对不同资源线程池的排队、超时情况分别进行处理,但这其实是超时熔断和流量控制要解决的问题,如果组件具备了超时熔断和流量控制的能力,线程池隔离就显得没有那么必要了。
Sentinel可以通过并发线程数模式的流量控制来提供信号量隔离的功能。这样的隔离非常轻量级,仅限制对某个资源调用的并发数,而不是显式地去创建线程池,所以 overhead比较小,但是效果不错。并且结合基于响应时间的熔断降级模式,可以在不稳定资源的平均响应时间比较高的时候自动降级,防止过多的慢调用占满并发数,影响整个系统。而 Hystrix的信号量隔离比较简单,无法对慢调用自动进行降级,只能等待客户端自己超时,因此仍然可能会出现级联阻塞的情况。
熔断降级对比 sentinel和Hystrix的熔断降级本质都是基于熔断器模式
Sentinel与 Hystrix都支持基于失败比率(异常比率)的熔断降级 此时所有对该资源的调用都会被 block,直到过了指定的时间窗口后才启发性地恢复。上面提到过,Sentinel还支持基于平均响应时间的熔断降级,可以在服务响应时间持续飙高的时候自动熔断,拒绝掉更多的请求,直到一段时间后才恢复。这样可以防止调用非常慢造成级联阻塞的情况。
Hystrix和 Sentinel的实时指标数据统计实现都是基于滑动窗口的。Hystrix 1.5之前的版本是通过环形数组实现的滑动窗口,通过锁配合 CAS的操作对每个桶的统计信息进行更新。Hystrix 1.5开始对实时指标统计的实现进行了重构,将指标统计数据结构抽象成了响应式流(reactive stream)的形式,方便消费者去利用指标信息。同时底层改造成了基于 RxJava的事件驱动模式,在服务调用成功/失败/超时的时候发布相应的事件,通过一系列的变换和聚合最终得到实时的指标统计数据流,可以被熔断器或 Dashboard消费。
Sentinel目前抽象出了 Metric指标统计接口,底层可以有不同的实现,目前默认的实现是基于LeapArray的滑动窗口,后续根据需要可能会引入 reactive stream等实现。
除了之前提到的两者的共同特性之外,Sentinel还提供以下的特色功能:
Sentinel作为一个功能完备的高可用流量管控组件,其核心sentinel-core没有任何多余依赖,打包后只有不到200K,非常轻量级,开发者可以放心引入 sentinel-core 而不需担心依赖问题,同时sentinel提供多种扩展点,用户可以很方便的根据需求去进行扩展,而且无缝切换到Sentinel中
引入Sentinel带来的性能损耗非常小。只有在业务单机量级超过 25W QPS的时候才会有一些显著的影响(5%- 10%左右),单机 QPS不太大的时候损耗几乎可以忽略不计。
Sentinel可以针对不同的调用以不同的运行指标 如 QPS、并发调用数、系统负载等)为基准,对资源调用进行流量控制,将随机的请求调整成合适的形状。
Sentinel支持多样化的流量整形策略,在 QPS过高的时候可以自动将流量调整成合适的形状。常用的有:
直接拒绝模式:即超出的请求直接拒绝。
慢启动预热模式:当流量激增的时候,控制流量通过的速率,让通过的流量缓缓的增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
匀速器模式 利用 Leaky Bucket算法实现的匀速模式,严格控制了请求通过的时间间隔,同时堆积的请求将会排队,超过超时时长的请求直接被拒绝。
隔离策略基于并发数线程池隔离/信号量隔离
熔断降级策略基于响应时间或失败比率基于失败比率
实时指标实现滑动窗口滑动窗口(基于 RxJava)
规则配置支持多种数据源支持多种数据源
调用链路信息支持同步调用不支持
限流基于 QPS/并发数,支持基于调用关系的限流不支持
流量整形支持慢启动、匀速器模式不支持
控制台开箱即用,可配置规则、查看秒级监控、机器发现等不完善
常见框架的适配Servlet、Spring Cloud、Dubbo、gRPC等Servlet、Spring Cloud Netflix
文章出处
三、Java学习路线
根据个人实际的经历,结合多种书籍,特别整理出了下面的java学习路线:
1、java基础:基础语法;面向对象(重点);集合框架(重点);常见类库API;
2、java界面编程:AWT;事件机制;Swing;
3、java高级知识:Annotation;IO和NIO、AIO;多线程、线程池;阻塞、非阻塞、异步网络通信;反射、动态代理;
4、SQL基础:基础SQL语句;基本查询;多表查询;子查询;结果集的交、并、差运算;
5、JDBC基础:常见数据库用法;JDBC操作常见数据库;RowSet与离线结果集;数据库连接池;事务管理、批处理;
6、JDBC进阶:存储过程、函数;触发器;理解JCBC的不足;掌握ORM工具优势和设计;
7、HTML基础:基本HTML标签;常见表单标签;DIV+CSS布局;
8、JavaScript知识:javascript基本语法;javascript基本对象特征;Json语法;深刻理解javascript的动态特征;
9、Dom和事件机制:DOM操作、编程;常见浏览器事件机制;掌握用户交互技巧;
10、XML基础:XML基础规则;DTD和SCheme;XML和样式单;
11、XML进阶:DOM、SAX和JAXP;dom4j、JDOM等工具;XQuery和XQJ;基于XML的数据交换;
12、Web Service:JAX_WS2、SAAJ规范;WSDL和SOAP协议;CXF框架、拦截器;CXF整合Spring;
13、Web编程基础:Tomcat服务器;Jsp语法、EL、内置对象;Servlet API;Servlet 3.0注解;Listener和Filter;
14、Web编程进阶:自定义标签库;MVC和DAO、Servlet、标签的作用;JSTL、DisplayTag等常见标签库用法;
15、Web编程原理:请求/响应、架构;Http协议;深刻理解Jsp运行原理;掌握Web容器底层的线程池、socket通信、调用Servlet的命令模式;
16、Ajax编程:XML HttpRequest和异步请求;发送请求和处理响应;常见Ajax库(Prototype、Jquery、ExtJs、DWR)用法;结合Http协议、异步请求深入研究ajax库的设计;
17、Android基础:Android开发调试环境;Android应用结构;界面组件与界面编程;资源管理;四大组件;
18、Android中级:文件IO和SQLite;图形、图像与动画;音频、视频的录制与播放;传感器编程;GPS应用;
19、Android高级:网络编程与Web Service;OpenGL_ES 3D开发;整合Google服务;使用NDK开发;java和c相互调试;
17、Struts2:MVC与struts体系;Action和Result;国际化和标签库;文件上传、下载;类型转换和输入检验;拦截器与插件开发;
18、Hibernate:ORM与持久化映射;关系映射、继承映射;延迟加载、性能调优;HQL查询、条件查询、SQL查询;二级缓存和查询缓存;
19、Spring:IoC与Bean配置、管理;Bean生命周期;SP、EL;AOP与事务权限控制;S2SH整合开发;Spring整合Jpa;
20、JSF<选学>:MVC与JSF设计理念;托管Bean与导航模型;JSF流程与事件机制;JSF标签库;类型转换与输入检验;
21、EJB及相关技术:JNPI与RMI;会话Bean及其生命周期;IoC与EJB拦截器;JMS与MDB;会话Bean与Web Service;
22、JPA:ORM框架与JPA规范;JPA注解与常用API;JTA事务与事务管理;JPQL查询;EJB、JPA整合;
23、Java EE实践与架构:Ant+Ivy或Maven;SVN、CVS;深刻理解10种以上设计模式;掌握各种Java EE架构及各自优势;
24、Workflow:Workflow规范及功能;JBPM等workflow框架;多次重构、反复思考;大型项目经验;
25、Java EE进阶:掌握各MVC框架运行原理、能开发类似框架;掌握Spring、HiveMind、AspectJ等框架原理、能开发类似工具;掌握Hibernate、iBatis等框架原理,能开发类似工具;深入研究EJB机制、大致了解应用服务器的实现;