Loading... 主要对比了Hystrix、Sentinel、Resilience4j | | Hystrix | Sentinel | resilience4j | | -------------- | --------------------- | ---------------------------------------------------------------------------- | ---------------------------------- | | 隔离策略 | 线程池隔离/信号量隔离 | 信号量隔离(并发线程数限流) | 信号量隔离 | | 熔断降级策略 | 基于异常比率 | 基于异常比率、响应时间、异常数 | 基于异常比率、响应时间 | | 实时统计实现 | 滑动窗口(基于RxJava) | 滑动窗口(LeapArray) | Ring bit Buffer | | 动态规则配置 | 支持多种数据源 | 支持多种数据源 | 有限支持 | | 扩展性 | 插件形式 | 多个扩展点 | 接口形式 | | 基于注解的支持 | 支持(静态方法不支持) | 支持 | 支持 | | 限流 | 有限支持 | 基于QPS,支持基于调用关系的限流 | Rate Limiter(令牌桶限流) | | 流量整形 | 不支持 | 支持预热模式、匀速器模式、预热排队模式 | 简单的Rate Limiter模式 | | 系统自适应保护 | 不支持 | 支持 | 不支持 | | 控制台 | 简单的监控查看 | 开箱即用的控制台,可配置规则、查看秒级监控、机器发现等(push模式需要手动配置) | 不提供控制台,但可对接其它监控系统 | | 文档完整性 | 完整 | 不完整 | 一般 | | 维护状态 | 不再维护 | 维护 | 维护 | ### Hystrix Hystrix 的关注点在于以 **隔离** 和 **熔断** 为主的容错机制,超时或被熔断的调用将会快速失败,并可以提供 fallback 机制。 **Hystrix 的资源模型设计上采用了命令模式,将对外部资源的调用和 fallback 逻辑封装成一个命令对象(HystrixCommand / HystrixObservableCommand),其底层的执行是基于 RxJava 实现的。每个 Command 创建时都要指定 commandKey 和 groupKey(用于区分资源)以及对应的隔离策略(线程池隔离 or 信号量隔离)。线程池隔离模式下需要配置线程池对应的参数(线程池名称、容量、排队超时等),然后 Command 就会在指定的线程池按照指定的容错策略执行;信号量隔离模式下需要配置最大并发数,执行 Command 时 Hystrix 就会限制其并发调用。** Hystrix 提供两种隔离策略:线程池隔离(Bulkhead Pattern)和信号量隔离,其中最推荐也是最常用的是线程池隔离。Hystrix 的线程池隔离针对不同的资源分别创建不同的线程池,不同服务调用都发生在不同的线程池中,在线程池排队、超时等阻塞情况时可以快速失败,并可以提供 fallback 机制。线程池隔离的好处是隔离度比较高,可以针对某个资源的线程池去进行处理而不影响其它资源,但是代价就是线程上下文切换的 overhead 比较大,特别是对低延时的调用有比较大的影响。 但是,实际情况下,线程池隔离并没有带来非常多的好处。首先就是过多的线程池会非常影响性能。考虑这样一个场景,在 Tomcat 之类的 Servlet 容器使用 Hystrix,本身 Tomcat 自身的线程数目就非常多了(可能到几十或一百多),如果加上 Hystrix 为各个资源创建的线程池,总共线程数目会非常多(几百个线程),这样上下文切换会有非常大的损耗。另外,线程池模式比较彻底的隔离性使得 Hystrix 可以针对不同资源线程池的排队、超时情况分别进行处理,但这其实是超时熔断和流量控制要解决的问题,如果组件具备了超时熔断和流量控制的能力,线程池隔离就显得没有那么必要了。 Hystrix 的信号量隔离限制对某个资源调用的并发数。这样的隔离非常轻量级,仅限制对某个资源调用的并发数,而不是显式地去创建线程池,所以 overhead 比较小,效果不错。但缺点是无法对慢调用自动进行降级,只能等待客户端自己超时,因此仍然可能会出现级联阻塞的情况。 --- ### Sentinel Sentinel 的核心思想:**根据对应资源配置的规则来为资源执行相应的流控/降级/系统保护策略。**在 Sentinel 中资源定义和规则配置是分离的。用户先通过 Sentinel API 给对应的业务逻辑定义资源,然后**可以在需要的时候动态配置规则。** Sentinel 可以通过并发线程数模式的流量控制来提供信号量隔离的功能。并且结合基于响应时间的熔断降级模式,可以在不稳定资源的平均响应时间比较高的时候自动降级,防止过多的慢调用占满并发数,影响整个系统。 从客户端API的形式来说,它相比于Hystrix来说更适合引入ETCD,且客户端API的形式也支持全局配置。 **优势:** **一、轻量级,核心库无多余依赖,性能损耗小。** **二、方便接入,开源生态广泛。** Sentinel 对 Dubbo、Spring Cloud、Web Servlet、gRPC 等常用框架提供适配模块,只需引入相应依赖并简单配置即可快速接入;同时针对自定义的场景 Sentinel 还提供低侵入性的注解资源定义方式,方便自定义接入。 **三、丰富的流量控制场景。** Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,流控维度包括流控指标、流控效果(塑形)、调用关系、热点、集群等各种维度,针对系统维度也提供自适应的保护机制。 **四、易用的控制台,提供实时监控、机器发现、规则管理等能力。** 由于Sentinel 的资源定义和规则配置是相分离的,因此只需要对资源配置熔断降级规则即可。如果接入了Sentinel 控制台,那么可以直接在 Sentinel 控制台上进行配置,更加方便。 **五、完善的扩展性设计。**提供多样化的 SPI 接口,方便用户根据需求给 Sentinel 添加自定义的逻辑。 **六、方便接入三方监控系统。**Sentinel 目前的监控支持 QPS、响应时间、限流数、异常数等几种指标。Sentinel 客户端每秒会把秒级的监控数据存储至本地日志,Sentinel 控制台进行拉取和聚合。在生产环境中,由于秒级监控数据的量非常大,我们一般将 metric 数据存储于列数据库或时序数据库中,并通过一些策略进行优化来保证监控存储和聚合的性能。 Sentinel 正在进行指标与监控标准化的相关工作,在完成标准化,抽出通用的 metric 接口后,即可快速对接 Zabbix 和 Prometheus 等监控系统,同时用户也可以方便地对接其它监控系统。 --- ### Resilience4j resilience4j 是一个比较轻量的熔断降级库。首先 resilience4j 的模块化做的比较好,将每个功能点(如熔断、限速器、自动重试)都拆成了单独的模块,这样整体结构很清晰,用户也只需要引入相应功能的依赖即可;另外**resilience4j 是针对 Java 8 和函数式编程设计的,API 比较简洁优雅。**同时与 Hystrix 相比,Resilience4j 增加了简单的限速器和自动重试特性,使用场景更加丰富。Resilience4j 属于一个新兴项目,社区也在蓬勃发展。总的来说,Resilience4j 是比较轻量的库,在较小较新的项目中使用还是比较方便的,但是 Resilience4j 只包含限流降级的基本场景,对于非常复杂的企业级服务架构可能无法很好地 cover 住;同时 Resilience4j 缺乏生产级别的配套设施(如提供规则管理和实时监控能力的控制台)。 --- 对于J2当前要对SOA请求做降级处理来说,Hystrix已经够用了,其它限流限频、监控等功能公司整套体系已经有在做了(网关、xy框架、Prometheus)。不足之处在于没办法通用配置所有的静态SOA请求的降级策略。 但对于后续系统的引入来说Sentinel的整个生态更加完备,可以更好的结合ETCD作为数据源,同时自带的控制台不仅十分简单易用,而且后续还能和运维的Prometheus进行一个对接。 Last modification:August 22, 2022 © Allow specification reprint Like 1 喵ฅฅ