本篇博客主要包括:限流方式、微服务容灾技术选型、Sentinel的使用、Sentinel动态规则持久化Zookeeper 等。
Sentinel动态规则持久化到Zookeeper的代码实现我已经共享到本人的github,有需要的可以下载使用。
github地址:https://github.com/Force-King/sentinel-dashboard-zk
持久化zk的sentinel-dashboard项目下载地址:https://github.com/Force-King/sentinel-dashboard-zk.git
一、限流方式
服务端限流
如果在服务端做限流,无论有多少个客户端,总的提供能力是固定的,所以不会因为客户端数量过多而导致资源不足,因为处理不过来的请求会被阻塞等待获取资源。
缺点
缺点也比较明显,由于服务提供者整体设置了最大限流数,此时所有的客户端共享同一份限流数据,那么有可能导致有的服务能分配到资源有些服务请求分配不到资源导致无法请求的情况。
客户端限流
客户端限流解决上服务端限流提到的问题,它能保证每个客户端都能得到响应。但是从其它方面考虑,必须针对不同的客户端做不同的限流策略:
- 请求量大,但时效性不高,此时将限流数控制小一些会比较合适
- 请求量大,但时效性高,此时将限流数适当调高
- 响应时间长,即慢接口,适当降低
- 主流业务,核心业务,适当调高
- 非主流业务,适当降低
缺点
- 如果客户端的数量不固定,那么有可能导致客户端数量过多造成大量请求打到服务端导致处理不了的结果,所以需要严格监控客户端的调用情况。
- 配置复杂,需要针对每个客户端做相对精准的判断
二、选型
1. 目前开源容灾框架有Hystrix、Sentinel、Resilience4j
Hystrix:常用于Spring Cloud的一个熔断降级组件。主要功能是不同服务之间的资源隔离、失败降级。底层实现是Rxjava。它提供两种资源隔离的模式:信号量隔离和线程池隔离。一般使用线程池隔离。耗费一定资源,但相比之下支持超时和异步执行。听起来可以覆盖大部分场景,但它不支持更高要求的流控,如qps的控制。所以需要单独采用令牌漏桶来做流量控制。
Sentinel:阿里开源的分布式流量控制组件。支持流控、熔断降级、系统保护等。所有的资源都对应一个资源名称以及一个Entry。每一个Entry创建的时候,同时也会创建一系列插件(系统保护插件:SystemSlot、流控插件:FlowSlot、熔断降级插件LDegradeSlot等)。每个插件会监控自己职责范围内的指标。NodeSelectorSlot将各个资源的调用路径以树状存储,用于限流降级。调用者通过创建上下文、请求token来执行方法。若没有抛出BlockException,表示请求成功。它支持并发数/qps的流量控制、也支持熔断降级。
Resilience4j:一个比较轻量的熔断降级库。模块化做的比较好,将每个功能点(如熔断、限速器、自动重试)都拆成了单独的模块,这样整体结构很清晰,用户也只需要引入相应功能的依赖即可;另外resilience4j 是针对 Java 8 和函数式编程设计的,API 比较简洁优雅。同时与 Hystrix 相比,Resilience4j 增加了简单的限速器和自动重试特性,使用场景更加丰富。Resilience4j 属于一个新兴项目,社区也在蓬勃发展。总的来说,Resilience4j 是比较轻量的库,在较小较新的项目中使用还是比较方便的,但是 Resilience4j 只包含限流降级的基本场景,对于非常复杂的企业级服务架构可能无法很好地 cover 住;同时 Resilience4j 缺乏生产级别的配套设施(如提供规则管理和实时监控能力的控制台)。
2. Sentinel 的优势和特性
- 轻量级,核心库无多余依赖,性能损耗小。
- 方便接入,开源生态广泛。
Sentinel 对 Dubbo、Spring Cloud、Web Servlet、gRPC 等常用框架提供适配模块,只需引入相应依赖并简单配置即可快 速接入;同时针对自定 义的场景 Sentinel 还提供低侵入性的注解资源定义方式,方便自定义接入。
- 丰富的流量控制场景。
Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,流控维度包括流控指标、流控效果(塑形)、调用关系、热点、集群等各种维度,针对系统维度也提供自适应的保护机制。
- 易用的控制台,提供实时监控、机器发现、规则管理等能力。
- 完善的扩展性设计,提供多样化的 SPI 接口,方便用户根据需求给 Sentinel 添加自定义的逻辑。
Sentinel 的主要特性