作者:阿里巴巴中间件
微信公众号:阿里巴巴中间件(ID:Aliware_2018)
导读:
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。流量控制、熔断降级、系统负载保护等技术被广泛使用于微服务体系,用以提升系统的健壮性和保障业务的稳定性,避免因访问流量过大、系统负载过重导致的系统停止服务的情况出现。
日前,Netflix开源的限流组件 Hystrix在其Github主页宣布,不再开放新功能,推荐开发者使用其他仍然活跃的开源项目。
Hystrix虽然不再开发新功能 ,但对用户的影响应该不会太大,一是因为开发者可以继续使用Hystrix的最新版本1.5.18,二是因为在Spring Cloud生态下,开发者还有其他限流的开源产品可以选择,例如Resilience4j和Sentinel。
Resilience4j,是一个受 Netflix Hystrix 启发的轻量级容错库,但是是为 Java 8和函数式编程设计的。轻量级,因为这个库只使用了 Vavr (以前叫做 Javaslang) ,没有任何其他的外部库依赖。相比之下,Netflix Hystrix 对 Archaius 有一个编译依赖,Archaius 有更多的外部库依赖,比如 Guava 和 Apache Commons configurations。
相比 Hystrix , Resilience4j的优势在于:
- 针对 Java 8 和函数式编程设计,提供函数式和响应式风格的 API;
- 增加了 rate limiting 和 automatic retrying 两个模块。其中 rate limiting 引入了简单的速率控制实现,补充了流量控制这一块的功能;
- 而 automatic retrying 则是封装了自动重试的逻辑,简化了异常恢复的流程。
Sentinel则是面向分布式服务架构的轻量级高可用流量控制组件,于今年7月正式开源。Sentinel 主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户提升服务的稳定性。
本文将详细介绍如何从Hystrix迁移到Sentinel,帮助开发者将此次事件的影响降到最低。
GitHub地址:
https://github.com/alibaba/Sentinel
Command 迁移
Hystrix 的执行模型设计上采用了命令模式,将对外部资源的调用逻辑和 fallback 逻辑封装成一个命令对象HystrixCommand / HystrixObservableCommand,交由 Hystrix 执行。一个最简单的例子:
而 Sentinel 并不指定执行模型,也不关注应用是如何执行的。在 Sentinel 中手动定义资源,只需要用 API 将其包装起来即可:
在 Hystrix 中,一般需要在 command 定义的时候就配置规则。而在 Sentinel 中资源定义和规则配置是分离的。用户先通过 Sentinel API 给对应的业务逻辑定义资源(埋点),然后可以在需要的时候配置规则。
线程池隔离
线程池隔离的好处是隔离度比较高,可以针对某个资源的线程池去进行处理而不影响其它资源,但是代价就是线程数目比较多,线程上下文切换的 overhead 比较大,特别是对低延时的调用有比较大的影响。Sentinel 没有提供线程池隔离这样比较重的隔离方式,而是提供了信号量隔离这种比较轻量级的隔离方式。
信号量隔离
Hystrix 的信号量隔离是在 Command 定义时配置的,比如:
而在 Sentinel 中,信号量隔离是作为流量控制的一种模式(线程数模式)提供的,因此只需要给资源配置线程数限流规则即可:
如果应用接入了 Sentinel 控制台,也可以方便地在控制台上进行配置。同个资源可以配置多种规则,多条规则。
熔断降级
Hystrix 熔断器支持异常比率熔断模式,主要有以下配置项:
circuitBreaker.errorThresholdPercentage
: 异常比率阈值,超出这个比率就会进行熔断circuitBreaker.sleepWindowInMilliseconds
: 熔断时长(保持 OPEN 状态的时长)
示例:
在 Sentinel 中只需要对希望自动熔断降级的资源配置降级规则即可。比如与上面 Hystrix 示例相对应的规则:
如果接入了 Sentinel 控制台,也可以在控制台上直接配置熔断降级规则。
除了异常比率模式之外,Sentinel 还支持根据平均响应时间、分钟级异常数进行自动熔断降级。
注解支持
Hystrix 提供了注解的方式来封装 command 并进行配置。以下是 Hystrix 注解的示例:
Hystrix command 执行和规则是捆绑在一起的,因此配置规则是在 @HystrixCommand
注解中的 commandProperties
属性中配置,比如:
而 Sentinel 并不指定执行模型,也不关注应用是如何执行的。Sentinel 的原则非常简单:根据对应资源配置的规则来为资源执行相应的限流/降级/负载保护策略。在 Sentinel 中资源定义和规则配置是分离的。用户先通过 Sentinel API 给对应的业务逻辑定义资源(埋点),然后可以在需要的时候配置规则。
使用 Sentinel 注解的方式和 Hystrix 类似,步骤如下:
- 引入注解支持依赖:
sentinel-annotation-aspectj
,并注入对应的 Aspect 实例(若使用 Spring Cloud Alibaba 则会自动注入,不需要额外配置); - 在需要进行限流/降级的方法上添加
@SentinelResource
注解并进行相应的配置(如配置fallback
函数,配置blockHandler
函数); - 配置规则
Sentinel 注解示例(相关文档):
配置规则按照 Sentinel 提供的配置规则的方式即可:
- 通过 API 来进行配置(如
DegradeRuleManager.loadRules(rules)
方法):
- 通过 Sentinel 控制台进行规则配置和管理
开源框架适配
Sentinel 目前已经针对 Servlet、Dubbo、Spring Cloud、gRPC 等进行了适配,用户只需引入相应依赖并进行简单配置即可快速地接入 Sentinel,无需修改现有代码。若之前在使用 Spring Cloud Netflix,可以考虑迁移到 Spring Cloud Alibaba 体系中。
动态配置
Sentinel 提供 动态规则数据源 支持来动态地管理、读取配置的规则。Sentinel 提供的 ReadableDataSource
和 WritableDataSource
接口简单易用,非常方便使用。
Sentinel 动态规则源针对常见的配置中心和远程存储进行适配,目前已支持 Nacos、ZooKeeper、Apollo、Redis 等多种动态规则源,可以覆盖到很多的生产场景。