原创 吴就业 140 0 2020-09-22
本文为博主原创文章,未经博主允许不得转载。
本文链接:https://wujiuye.com/article/8eb485ee87a543c6b832a2feec8e9850
作者:吴就业
链接:https://wujiuye.com/article/8eb485ee87a543c6b832a2feec8e9850
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。
为什么选择Sentinel?选择Sentinel与Hystrix通常第一步都是通过对比两者优缺点,Sentinel与Hystrix的对比结果是作为我们选择Sentinel还是Hystrix的直观参考,不过使用Sentinel能做什么,是否满足实际需求才是我们最终决定是否使用Sentinel的最关键因素,否则尽管一个框架再好,不适合也不会选择。
以下Sentinel与Hystrix的对比表格来自Sentinel Github官方文档。
Sentinel | Hystrix | |
---|---|---|
隔离策略 | 信号量隔离 | 线程池隔离/信号量隔离 |
熔断降级策略 | 基于响应时间或失败比率 | 基于失败比率 |
实时指标实现 | 滑动窗口 | 滑动窗口(基于 RxJava) |
规则配置 | 支持多种数据源 | 支持多种数据源 |
扩展性 | 多个SPI扩展点 | 插件的形式 |
基于注解的支持 | 支持 | 支持 |
限流 | 基于 QPS,支持基于调用关系的限流 | 有限的支持 |
流量整形 | 支持慢启动、匀速器模式 | 不支持 |
系统负载保护 | 支持 | 不支持 |
控制台 | 开箱即用,可配置规则、查看秒级监控、机器发现等 | 不完善 |
常见框架的适配 | Servlet、Spring Cloud、Dubbo、gRPC 等 | Servlet、Spring Cloud Netflix |
Sentinel于18年7月份开源,截至本文写作之日已有13k的Star,而Hystrix已经停止开发。Hystrix不再维护可能也是Sentinel能快速进入大家眼球的原因之一。Hystrix虽然不再维护,但依然开源,且Hystrix已经很稳定,不会因为不维护就不可用,只是不会再有更新。相比Hystrix,Sentinel更易于上手,Sentinel是国内开源的项目,官方有提供中文文档,因此对只会中文的开发者较为友好,并且文档介绍的也很全面。
Hystrix最核心的一项功能就是资源隔离,支持线程池隔离和信号量隔离。Sentinel不支持线程池隔离,但使用Sentinel也可通过控制并发线程数方式提供信号量隔离。例如,控制服务A同时只能有5个线程去调用服务B的某个接口,或者控制服务B同时只能有5个线程去处理服务A发起调用的某个接口,避免因为一个接口消耗全部线程资源,导致服务奔溃。Hystrix的线程池隔离可以为每个资源配置单独的线程池用于发送请求,但资源多的情况下会导致线程池增多,线程池增多会导致线程数增多,上下文切换会有非常大的损耗,对低延时的调用影响较大,因此Hystrix的线程池隔离也并未体现出多大的优势。
Sentinel与Hystrix都支持基于失败比率的熔断降级,在调用超过指定的数量并且失败比率达到设定的阈值时触发熔断,并在下个时间窗口自动恢复。Sentinel也支持按失败总数熔断降级,但按失败总数的熔断降级固定时间窗口为1分钟,当1分钟内调用失败总数达到设定的阈值就会触发熔断。除此之外,Sentinel还支持基于平均响应时间的熔断降级,平均响应时间越长,说明服务的性能在持续下降,在响应时间持续飙高时自动熔断,可以防止调用慢造成级联阻塞。
Sentinel和旧版本Hystrix的实时指标数据统计实现都是基于滑动窗口,指标数据统计指的是统计每个资源的当前窗口时间内的请求总数、处理成功总数、失败总数、总耗时、平均耗时、最大耗时、最小耗时、被降级总数等。使用滑动窗口可以循环利用一个数组,不需要重新申请内存,也不需要去删除过期的统计数据,降低GC的压力。Hystrix 1.5 版本对实时指标统计的实现进行了重构,将指标统计数据结构抽象成响应式流(reactive stream)的形式,方便消费者去利用指标信息,同时底层改造成基于 RxJava 的事件驱动模式,在服务调用成功、失败或超时时发布事件,通过一系列的变换和聚合最终得到实时的指标统计数据流,可以被熔断器或 Dashboard 消费[1]。Sentinel官方表示,未来将支持响应式流。
Sentinel提供数据源接口可实现动态加载规则配置,结合loadRules API可灵活的运行时修改规则配置,并且随时修改随时生效。动态修改不仅支持修改某资源的规则配置,也支持添加新的资源规则配置或者移除资源规则配置。Sentinel支持给同一个资源同时添加多种规则配置,当对同一个资源配置多种规则时,哪个规则先达到阈值就会触发哪个规则的降级。Hystrix 的资源模型设计上采用了命令模式,在创建 Command 时就需要指定隔离策略是线程池隔离还是信号量隔离,一但指定了隔离策略,运行期间便不能修改隔离策略,而在 Sentinel 中资源定义和规则配置是分离的,因此在配置的灵活性上Sentinel更具有优势。
Sentinel支持系统自适应限流,Hystrix所不支持的。当系统负载较高的时候,如果仍持续让请求进入,可能会导致系统崩溃,无法响应。在集群环境下,负载均衡把本应这台机器承载的流量转发到其它的机器上去,如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器崩溃,最后导致整个集群不可用。针对这个情况,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求[2]。
在QPS过高的情况下,直接拒绝超出限制的请求是最常见的实现方式,但有些场景我们可能并不想直接拒绝请求,而是让请求排队等待处理,例如某一秒突增请求过多,但下一秒可能又没有请求或者请求很少的情况。Sentinel的流量控制支持多种模式,例如直接拒绝模式、慢启动预热模式、匀速器模式。而慢启动预热模式和匀速器模式也是Hystrix所不支持的。
Sentinel在框架的设计上使用了责任链模式和SPI机制提供扩展功能。使用SPI机制为Sentinel提供了更好的扩展性,例如,使用SPI支持自定义调用链构建器,使用自定义调用链构建器可实现按需选配降级功能(ProcessorSlot),并且还可以自己添加自定义降级功能(ProcessorSlot)。简单说,我们可以实现自定义降级功能,或者根据需要选择Sentinel提供的降级功能,移除不需要的,尽量降低Sentinel对服务的性能影响。
Sentinel还支持集群限流。除了轮询负载均衡算法外,其它的算法都会导致流量到集群的每个节点都不一样,有的多有的少,假设服务B部署两个节点,对每个节点配置限流阈值为200 QPS,我们希望集群的整体限量阈值是400 QPS,但实际情况可能400个请求有300个请求分配到节点1,只有100个请求分配到节点2,导致总量没有到的情况下节点1就开始限流,因此单机维度限流会无法精确地限制总体流量。
集群流控可以精确地控制整个集群的调用总量,结合单机限流兜底,可以更好地发挥流量控制的效果。但实现集群限量需要一个server专门统计集群的总调用量,其它的实例都要与server 通信来判断是否可以调用,也意味着每个请求都要增加一次额外的与server通信的消耗,不过在使用单一长连接且server处理“判断是否能通过”的耗时非常低,这个消耗对性能的影响还是可以接受的。
另外,黑白名单限流和热点参数限流也是Sentinel的一大特色。
黑白名单限流,可根据请求来源判断来源是否在黑名单中,如果在黑名单中则拒绝请求,否则放行,结合Sentinel的灵活动态配置,黑白名单可用于高峰期间对某些服务限流。
热点参数限流,统计调用SphU.entry传入参数中的热点参数,根据配置的限流阈值对包含热点参数的资源调用进行限流。热点参数限流仅对包含热点参数的资源调用生效,Sentinel利用LRU策略统计最近最常访问的热点参数,结合令牌桶算法进行参数级别的流控,并且支持匀速流控效果。例如,想对某个热卖的商品限流,可将商品的ID为参数,统计一段时间内访问量最多的商品并进行限制。
Sentinel提供的多种限流功能基本满足我们的所有需求,并且提供切入点让使用者可扩展Sentinel的功能,加上灵活的规则配置,以及Sentinel在性能上所作出的努力,都是Sentinel被广泛使用的原因。Sentinel有阿里巴巴做信用背书,也在不断的优化、不断更新,相信Sentinel能做得更好。
声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。
本篇内容介绍如何使用r2dbc-mysql驱动程序包与mysql数据库建立连接、使用r2dbc-pool获取数据库连接、Spring-Data-R2DBC增删改查API、事务的使用,以及R2DBC Repository。
消息推送服务主要是处理同步给用户推送短信通知或是异步推送短信通知、微信模板消息通知等。本篇介绍如何使用Spring WebFlux + R2DBC搭建消息推送服务。
IDEA有着极强的扩展功能,它提供插件扩展支持,让开发者能够参与到IDEA生态建设中,为更多开发者提供便利、提高开发效率。我们常用的插件有Lombok、Mybatis插件,这些插件都大大提高了我们的开发效率。即便IDEA功能已经很强大,并且也已有很多的插件,但也不可能面面俱到,有时候我们需要自给自足。
Instrumentation之所以难驾驭,在于需要了解Java类加载机制以及字节码,一不小心就能遇到各种陌生的Exception。笔者在实现Java探针时就踩过不少坑,其中一类就是类加载相关的问题,也是本篇所要跟大家分享的。
订阅
订阅新文章发布通知吧,不错过精彩内容!
输入邮箱,提交后我们会给您发送一封邮件,您需点击邮件中的链接完成订阅设置。