这是围绕 Sentinel 的使用场景、技术对比和实现、开发者实践等维度推出的系列文章的第二篇。
第一篇:Dubbo 的流量防卫兵 | Sentinel如何通过限流实现服务的高可用性 - 链接
本期将通过 Sentinel 的匀速请求和冷启动的特性,处理消息场景中经常会遇到的消息突刺的情况,通过“削峰填谷”,来打造服务的稳定性。
» 8月26日,Aliware Open Source 将首次在成都举办 Apache Dubbo 的meetup活动,Dubbo 、Sentinel和 Nacos 的小哥哥和小姐姐都会在现场进行技术分享,欢迎成都的朋友报名参加我们的活动喔,公众号后台发送“成都meetup”,获取报名链接。
一、需求场景描述
在 RocketMQ 中,当消费者去消费消息的时候,无论是通过 pull 的方式还是 push 的方式,都可能会出现大批量的消息突刺。如果此时要处理所有消息,很可能会导致系统负载过高,影响稳定性。但其实可能后面几秒之内都没有消息投递,若直接把多余的消息丢掉则没有充分利用系统处理消息的能力。
我们可以看到消息突刺往往都是瞬时的、不规律的,其后一段时间系统往往都会有空闲资源。我们希望把红色的那部分消息平摊到后面空闲时去处理,这样既可以保证系统负载处在一个稳定的水位,又可以尽可能地处理更多消息,这时候我们可以通过 Sentinel匀速请求的特性 ,来为 RocketMQ 削峰填谷,保驾护航。
二、Apache RocketMQ 一键接入 Sentinel
1、实时监控:
Sentinel 提供 API 用于获取实时的监控信息,使用时可以添加以下依赖:
API 接入文档:
https://github.com/alibaba/Sentinel/wiki/实时监控
为了便于使用,Sentinel 还提供了一个控制台(Dashboard)用于配置规则、查看监控、机器发现等功能。我们只需要按照 Sentinel 控制台文档 启动控制台,然后给对应的应用程序添加相应参数并启动即可(注意客户端需要添加上面的 transport 依赖)。
控制台文档:
https://github.com/alibaba/Sentinel/wiki/控制台
这样在启动 Consumer 示例以后,就可以在 Sentinel 控制台中找到我们的应用了。可以很方便地在控制台中配置限流规则:
或者查看实时监控(这里对应匀速模式,图中标注的 b_qps 代表每秒被 block 的数目,下同):
对比普通限流模式下的监控图线:
可以看到普通限流模式下每次流量突刺都只能在一瞬间处理少量消息,其它请求都会立即被限掉。而匀速模式下可以把突刺的部分平滑到后面的时间中处理,每次消息量激增时都可以处理更多的消息。两种模式对比说明匀速模式下消息处理能力得到了更好的利用。
2、一键接入
在结合 RocketMQ Client 使用 Sentinel 时,用户首先需要引入 sentinel-core 依赖,由于 RocketMQ Client 未提供相应拦截机制,而且每次收到都可能是批量的消息,因此用户在处理消息时需要手动进行埋点。在 RocketMQ 的场景中,用户可以根据不同的 group 和不同的 topic 分别设置限流规则,开启匀速器模式,并在处理消息时埋点,即可以以固定的速率处理消息。然后在处理消息的时候手动埋点(以 pull consumer 为例):
PullConsumerDemo地址:
https://github.com/alibaba/Sentinel/blob/master/sentinel-demo/sentinel-demo-rocketmq/src/main/java/com/alibaba/csp/sentinel/demo/rocketmq/PullConsumerDemo.java
下面我们来看一下具体的运行效果。首先根据 RocketMQ 的文档来在本地启动 RocketMQ,然后向对应 group 的对应 topic 发送 1000 条消息,然后按上面的例子配限流规则,启动消费者应用。可以看到消息消费的速率是匀速的,大约每 200 ms 消费一条消息。同时不断有排队的处理任务完成,超出等待时长的处理请求直接被拒绝。注意在处理请求被拒绝的时候,需要根据需求决定是否需要重新消费消息。
如果不开启匀速模式,只是普通的限流模式,则只会同时处理 5 条消息,其余的全部被拒绝,即使后面的时间系统资源充足多余的请求也无法被处理,因而浪费了许多空闲资源。
三、Sentinel 基于 Apache RocketMQ 的最佳实践
1、匀速器
借助 Sentinel 匀速请求的特性,可以把突然到来的大量请求以匀速的形式均摊,以固定的间隔时间让请求通过,以稳定的速度逐步处理这些请求,从而避免流量突刺造成系统负载过高。同时堆积的请求将会排队,逐步进行处理;当请求排队预计超过最大超时时长的时候则直接拒绝,而不是拒绝全部请求。
匀速器Demo 示例:
https://github.com/alibaba/Sentinel/wikii/限流---匀速器
比如在 RocketMQ 的场景下配置了匀速模式下请求 QPS 为 5,则会每 200 ms 处理一条消息,多余的处理任务将排队;同时设置了超时时间为 5s,预计排队时长超过 5s 的处理任务将会直接被拒绝。示意图如下:
2、冷启动
除了匀速器,另一种在面对RocketMQ 场景下流量突增时来保障系统稳定性的的方式是冷启动。该方式主要用于系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮的情况。具体的例子参见 WarmUpFlowDemo。
通常冷启动的过程系统允许通过的 QPS 曲线如下图所示:
通过前两期的分享,我们已经理解了 Sentinel 在 Dubbo和RocketMQ 这两个体系中的使用场景和实践方法,在下一周的第三期中,我们将对比Sentinel和传统的限流产品Hystrix,希望对开发者在进行限流产品的技术选型时有所裨益。