程序员必知的分布式容错和降级技术
可以参与抽奖
参与方式
关注公众号:35岁程序员那些事,后台回复关键词“参与抽奖”,获取抽奖链接,点击抽奖。 中奖之后,可以联系笔者的微信号或者公众号后台回复关键词“联系笔者”,获取联系方式。
分布式容错和降级是微服务架构中应对瞬时大流量的最佳解决方案。
推荐使用Spring Cloud Alibaba+Sentinel
Nginx
Nginx是一块轻量级的Web服务器/反向代理服务器,目前在github上Star 13.3k Fork 4.9k Watch 951,整体关注度也非常高,最近一次更新是2020年12月5日,最新的版本为release-1.19.6。
那么如何使用Nginx进行应用的分布式容错和降级呢?答案就是Nginx+Lua可以实现分布式容错和降级,利用Lua脚本可以实现限流算法,并从应用接入层做容错和降级。
Guava
Guava是一种基于开源的Java库,其中包含谷歌内部使用的很多核心库。这个库是为了方便编码,并减少编码错误。这个库提供了用于集合、缓存、支持原语、并发性、常见注解、字符串处理、I/O等实用方法API,这些都是谷歌开发者结合自身业务场景的最佳实践,可以说是一块非常优秀的开源中间件框架。
Guava - RateLimiter使用的是一种叫令牌桶的流控算法,RateLimiter会按照一定的频率往桶里扔令牌,线程拿到令牌才能执行。
Guava目前在github上Star 40k Fork 8.9k Watch 2.5k,最近一次更新是2020年12月15日,最新版本为30.1,无论是开源的关注度和活跃度都非常高。
Redis
Redis是互联网技术领域使用最为广泛的存储中间件,它是“Remote Dictionary Service”(远程字典服务)的首字母缩写。Redis以其超高的性能、完美的文档、简洁易懂的源码和丰富的客户端库支持在开源中间件领域广受好评。
Redis采用C语言开发,目前在github上Star 47k Fork 18.5k Watch 2.7k,关注度也非常高,最近一次更新是2021年1月12日,目前最新版本为6.0.10,社区更新活跃度非常高。
在Redis中,有5种基础数据结构,分别为:string(字符串)、list(列表)、hash(字典)、set(集合)和zset(有序集合),合理的利用这些数据结构是可以达到分布式限流的效果,比如通过zset数据结构中的score值,来构造一个时间窗口,作为限流的滑动窗口,这样就可以快速的构造一个分布式限流算法。
Hystrix
Hystrix是Netflix公司开源的一款容错框架,包含常用的容错方法:线程池隔离、信号量隔离、熔断和降级回退。在高并发访问下,系统所依赖的服务的稳定性对系统的影响非常大,依赖有很多不可控的因素,比如网络连接变慢、资源突然繁忙、暂时不可用、服务宕机等。我们要构建稳定、可靠的分布式系统,就必须要有一套容错的解决方案。
Hystrix目前在github上Star 20.9k fork 4.3k Watch 1.7k,可以说关注度非常高,但是最近一次版本更新是2018年11月17日,版本为v1.5.18,已经有两年没更新代码。
Resilience4j
Resilience4j 是一个比较轻量的熔断降级库。
首先,Resilience4j 的模块化做的比较好,将每个功能点(如熔断、限速器、自动重试)都拆成了单独的模块,这样整体结构很清晰,用户也只需要引入相应功能的依赖即可。
另外,Resilience4jR是针对 Java 8 和函数式编程设计的,API 比较简洁优雅。
同时,与 Hystrix 相比,Resilience4j 增加了简单的限速器和自动重试特性,使用场景更加丰富。Resilience4j 属于一个新兴项目,社区也在蓬勃发展。
总的来说,Resilience4j 是比较轻量的库,在较小较新的项目中使用还是比较方便的。但是 Resilience4j 只包含限流降级的基本场景,对于非常复杂的企业级服务架构可能无法很好地 cover 住;同时 Resilience4j 缺乏生产级别的配套设施(如提供规则管理和实时监控能力的控制台)。
Resilience4j目前在github上Star 6.4k Fork 857 Watch 215,最近一次版本更新是2020年10月19号,最新的release版本是v1.6.1。
Sentinel
Sentinel 一款面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助用户保障服务的稳定性。
Sentinel 的核心思想:根据对应资源配置的规则来为资源执行相应的流控/降级/系统保护策略。在 Sentinel 中资源定义和规则配置是分离的。用户先通过 Sentinel API 给对应的业务逻辑定义资源,然后可以在需要的时候动态配置规则。
Sentinel 的优势和特性:
-
轻量级,核心库无多余依赖,性能损耗小;
-
方便接入,开源生态广泛。Sentinel对Dubbo、Spring Cloud、Web Servlet、gRPC等常用框架提供适配模块,只需引入相应依赖并简单配置即可快速接入;同时针对自定义的场景Sentinel还提供低侵入性的注解资源定义方式,方便自定义接入;
-
丰富的流量控制场景。Sentinel承接了阿里巴巴近10年的双十一大促流量的核心场景,流控维度包括流控指标、流控效果(塑形)、调用关系、热点、集群等各种维度,针对系统维度也提供自适应的保护机制;
-
易用的控制台,提供实时监控、机器发现、规则管理等能力;
-
完善的扩展性设计,提供多样化的 SPI 接口,方便用户根据需求给 Sentinel 添加自定义的逻辑。
对比以上几种解决方案
Nginx和Redis具备一定的分布式容错和降级能力,但是从功能完整性角度肯定是不如Sentinel、Hystrix和Resilience4j,Guava虽然也具备容错和降级能力,但是不具备分布式能力,它是基于单实例JVM的。基于以上原因,这里就对比下Sentinel、Hystrix和Resilience4j。
| Sentinel | Hystrix | Resilience4j |
隔离策略 | 信号量隔离(并发线程数限流) | 线程池隔离/信号量隔离 | 信号量隔离 |
熔断降级策略 | 基于响应时间、异常比率、异常数 | 基于异常比率 | 基于异常比率、响应时间 |
实时指标实现 | 滑动窗口(LeapArray) | 滑动窗口(基于RxJava) | Ring Bit Buffer |
动态规则配置 | 支持多种数据源 | 支持多种数据源 | 有限支持 |
扩展性 | 多个扩展点 | 插件形式 | SDK形式 |
基于注解的支持 | 支持 | 支持 | 支持 |
限流 | 基于QPS限流和基于调用关系限流 | 有限的支持 | Rate Limiter |
流量整形 | 支持预热模式、匀速器模式和预热排队模式 | 不支持 | 简单的Rate Limiter模式 |
系统自适应保护 | 支持 | 不支持 | 不支持 |
控制台 | 提供开箱即用的控制台,可配置规则、查看秒级监控、机器治理等。 | 简单的监控查看 | 不提供控制台,可对接其它监控系统。 |
常见框架适配 | Servlet、HttpClient、Dubbo、Spring Web等 | Servlet、Spring Cloud Netflix | 部分支持 |
总结
推荐使用Spring Cloud Alibaba+Sentinel,可以从服务治理和流量治理,两重维度去治理微服务,高效、简单并且符合主流。