前言
你在工作中是否遇到过这些问题?系统平时访问流量平平,在某个时间段好像决堤似的突增?上下游执行链路长,重要和不重要的执行内容混在一起,层层嵌套?面对高并发时,下游系统无法承载海量的调用量,影响上游响应……如果你也有,那就和我一起来学习rocketMq吧,据说rocketMq能帮我们很好的解决这些问题。
一、rocketMq是什么?
Apache rocketMq是阿里开发的一款具有低延迟,高可靠的,万亿级容量,可灵活扩展的分布式消息队列。由4部分组成:nameSrv,broker,producer,consumer,每部分都支持水平扩展。
nameSrv:提供轻量级的服务发现与路由,每个nameSrv都记录完整的路由信息,起到注册中心的作用。与ZooKeeper不同的是,nameSrv的每个节点彼此不通信,无状态,无主从。
broker:提供轻量级的topic和queue机制来存储消息。
producer:消息生产者。
consumer:消息消费者。
从官方文档了解到,因为早期的ActiveMq5.X无法支持业务吞吐量的增大,而Kafka在低延迟和高可靠方面无法满足要求,于是技术团队发明一个新的消息传递引擎来处理更广泛的用例集,从传统的发布/订阅场景到大容量实时零丢失容忍交易系统,就是rocketMq。官方文档给出了activeMq,kafka,rocketMq的对比,从一个CSDN博主的文章中还读到了与RabbitMq 对比,一起看下
二、rocketMq的应用
异步解耦
1、异步解耦,“缩短”执行链路
举个例子,在商城系统中用户取消订单时,至少需要做这几步:
①调用订单系统更新订单状态为取消;
②调用计费系统费用计算和退款;
③调用优惠券系统退还用户优惠券(②和③也可能在一个流程里;有些公司优惠券系统和计费系统是两个系统);
④通知商家;
⑤多平台合作的情况下,通知到其他平台订单已取消;
在大型的商城项目中需要执行节点可能更多,比如淘宝系统,可能还会累积用户取消次数,取消次数达到阈值后,将用户列入风控名单,限制用户购买运费险等。如果这些操作我们放到一个线程里执行,执行的步骤越多,给用户响应会越慢;上一步执行失败可能会影响后面的操作无法执行;有些步骤执行失败后可能需要重试……所有执行节点耦合在一起,一笔订单取消用3s以上都有可能,而我们正常的APP响应,超过500ms,都会感觉到卡顿,这样肯定不行。
所以,我们必须把执行步骤解耦。用户最关注步骤①和②的执行结果,所以①和②的优先级最高,执行完成后需要立刻返回;③④⑤可以晚点告知用户,优先级相对降低,且③④⑤不依赖彼此的执行结果,所以我们可以新建一个线程池专门执行③④⑤,并分别添加异常处理。这时候,我们使用新建线程池的方式完成了解耦操作。
随着使用系统的人数增多,订单量越来越多,系统的QPS持续升高,机器的负载也越来越高,系统响应时长又变慢了,怎么办呢? 你可能会说,都这时候了,那肯定是扩容啊。是的,那怎么个扩法呢?
方法一:横向扩展,把项目往服务器上多部署几个;
方法二:使用rocketMq;我们之前是新建了一个线程池,专门执行③④⑤。方法二简单来说就是换一种异步执行的方式,把③④⑤迁到新的系统ConsumerProject,原系统简称OrderProject。当①②执行完成,发送消息到消息队列,ConsumerProject建立监听,监听到消息后执行③④⑤。
方法二的好处是我们可以根据系统负载情况对OrderProject 和ConsumerProject 分别扩容,比如在机器有限的情况下,OrderProject 可以优先部署在性能相对比较好的机器上,可能部署2个实例就够了;ConsumerProject 执行的步骤比较多,可以根据情况多部署几个实例。这样通过rocketMq可以很好的将执行链路“缩短”,对操作步骤解耦。
2、减少下游对上游的影响
还用1的例子,当优惠券系统响应慢或者宕机了,因为③在ConsumerProject中执行,所以此时最多也只影响到ConsumerProject工程,不会影响到OrderProject工程。用户收到优惠券退还的通知会晚一点,但订单取消和退款都能正常进行。
削峰平谷
以秒杀系统为例,用户的请求量在短时间内暴增,消费者消费消息时,很可能出现因消息发送量突增而来不及处理的情况,导致消费方负载过高,进而导致影响系统稳定性。在实际场景中,消息的到来具有瞬时性、不规律性,导致系统可能出现空闲资源。rocketMq削峰平谷就是把超过消费端处理能力的消息(图中黄色部分)均摊到后面系统空闲时去处理,让系统负载处在一个稳定的水位,同时尽可能地处理更多消息。
(来自AHAS为消息队列RocketMQ版消费端削峰填谷 - 应用高可用服务 AHAS - 阿里云)
除了使用AHAS,我认为还可以使用rocketMq的拉取模式,根据消费者的消费能力和业务场景自定义拉取方式来处理消息。
三、总结
这篇rocketMq入门,我们从rocketMq是什么,和其他消息队列的对比入手,对rocketMq 有了一个总体的认识。同时通过结合场景,我们看到了rocketMq 在异步解耦,削峰平谷上发挥的巨大力量,后面我们将结合配置和源码对rocketMq进行更加深入的认识,敬请期待。