《消息队列高手课》一:一些基本概念

本章内容主要来自极客时间《消息队列高手课》文章的总结和摘录,结合部分自身的思考。

为什么需要消息队列

消息队列的作用

类比工厂流水线生产,上下游工序之间需要通信,比如告诉下游“我生产好了,你来获取我的产物吧!“。消息队列可以解决上下游通信的问题。在分布式环境中,上游和下游会存在与不同的物理节点。

上游工序单个产物和下游工序单个产物的速度不一致,比如上游是给车刷漆需要三分钟,但是下游给车安装皮质沙发、调试车机系统可能需要大半天。上游刷完漆的车壳可能会堆积起来,正常的想法就是”找个厂房堆积一下“等下游工序来取,消息队列也是这么做的,至此,消息队列又有了第二个作用,就是解决上下游工序速度不一致的问题,提供缓存的功能来实现。

至此,我们可以从过上述的描述提炼出两个作用:通信、缓存

消费队列有什么问题和局限性

  1. 引入MQ,可能会带来一定的延迟
  2. 系统复杂度增加,开发、运维的难度增加
  3. 数据不一致的问题

使用消息队列的应用场景

异步处理

举个秒杀系统的例子,如果我们去秒杀物品,假如秒杀请求的完整处理周期如下所示:

image-20220224124851393

也就是:风险控制→库存锁定→生成订单→短信通知→更新统计数据,五个步骤。

但是经验告诉我们。一般经过服务端的两道工序:“风控 → 改库存”。基本上就能确定我秒杀的结果。后续的生成订单、发送短信到我手机上的功能,其实采用异步的方式去处理即可。”异步的方式去处理“,这就是MQ的应用场景之一。当修改完秒杀产品的库存之后我可以立即返回给客户秒杀的结果。不需要等待后续的订单生成、短信发送...工序的完成再告诉客户,这有什么好处?。

  1. 服务响应时间缩短
  2. 异步执行任务,并发处理 → 整体吞吐量提升 ↑。

流量控制

消息队列实现流量控制有两种方式:

方式一:MQ隔离网关和秒杀服务

第二个应用场景是"流量控制"。秒杀的请求短时间涌入,使用消息队列隔离网关和真正的秒杀服务。将秒杀请求存入消息队列,秒杀服务按照自己最大能力去消费消息。如果请求超时则说明本次秒杀服务失败,"您没有抢到您喜欢的倒钩鞋"。这样做能够实现流量控制,达到削峰填谷的作用,运维还可以在秒杀请求支持度高的情况下水平扩容,更好的满足用户的秒杀请求。

为什么人要修建水库,无非就是在雨季雨水多的时候可以存蓄更多的水防止洪水冲垮村庄。MQ在这里也是相同的作用。

这样做有什么不好的地方?

  1. 调用链增长,因为节点增多了。
  2. 上下游异步处理增多了,为了实现可靠性,必定要增加系统复杂度。

方式二:MQ创建令牌桶

第二种流量控制的方式被称为"令牌桶"。首先我们可以预估秒杀请求的数量,在一个“桶”里面存放"令牌",这个令牌是参与秒杀的通行证,如果你没有令牌,那么你的秒杀请求我可以直接拒绝掉。

实现的角度来说,就是在网关处理请求时候增加一个获得令牌的逻辑。这个令牌从哪里来?我按照预先估计的秒杀请求的数量设置一个消息队列,有一个令牌消息生产者匀速的往里面push令牌数据进去。网关收到秒杀请求,先去消息队列里面拿取令牌:

  1. 拿到令牌成功,继续后续的风控和库存扣减流程
  2. 拿不到令牌,直接拒绝此次请求。

服务解耦

当上下游之间的工序过长且变化很多的时候,应用之间的解耦就体现的非常重要,比如一个订单的完成需要涉及到多个服务,比如支付、客服、短信、风控...。这一系列的操作都离不开实时的获取订单服务。为了响应订单服务流程中的各个服务的变化,开发团队人员往往要为了适配上下游接口不断的迭代上线。服务的停止会给用户带来不好的体验。

引入消息队列之后,一旦生产出来一个订单消息,广播发送给所有消费者之后,各个消费者各取所需得到订单消息,并发的去处理响应的操作。这样做有什么好处?——各自的迭代影响范围小,实现了服务和服务之间的解耦。

三大应用场景之外的其他应用场景

使用MQ,其实我们还可以去做到:

  1. 实现服务之间的发布/订阅系统。2022年03月21日目前所在公司的主要应用场景就在此,发布订阅响应来自中台的一些业务处理。
  2. 连接流计算任务和数据
  3. 广播一份消息给大量的消费者

实际上,单体应用可以使用Queue数据结构的地方,在分布式里面都可以使用MQ来解决。

消息队列产品之间的介绍和比较

怎么选消息队列产品

系统技术选型的时候,针对消息队列产品,在选择的时候我们需要考虑什么

  1. 是否开源,开源意味着对源代码有定制的可能性。
  2. 开源社区活跃度
  3. 和周边的生态系统是否有比较好的继承和兼容 比如kafka和flink集成度很不错
  4. 是否具备如下好的消息队列应该有的特性:
    1. 消息传递可靠
    2. 支持集训
    3. 性能优秀

有哪些消息队列产品

目前市面上可供选择的消息队列产品有RabbitMQ、RocketMQ和Kafka,列出特点、优缺点如下:

优/特点 缺点
RabbitMQ 使用erlang语言开发,支持 AMQP 协议的消息队列,特点是:

1. 轻量级和快速,使用/部署起来容易。
2. 技术方面,支持灵活的路由配置,生产者(Producer)和队列(Queue)之间增加了一个 Exchange 模块。起到一个“交换机”的作用。
3. 支持的编程语言特别多 包括部分冷门语言
缺点比较明显:

1. 消息堆积的支持度不好,一旦堆积,性能急速下降。
2. 性能较差,每秒钟几万~十几万条消息处理速度。
3. 运维以及二次开发支持度较差,erlang语言比较冷门。
RocketMQ 1. Java语言开发

2. 性能、稳定性和可靠性不错,性能大概美妙几十万条消息处理速度。
3. 在线业务的响应时延优化很不错,毫秒级响应 这个是RocketMQ的卖点
在国际上流行度不高,周边生态系统集成兼容性不够好。
Kafka 1. 由linkdin开发
2. 周边生态系统兼容性好,尤其出现在大数据、流计算领域
3. Scala 和 Java 语言开发,批量、异步的思想充分使用
4. 性能优异,极限情况下可以美妙处理2000万的消息
牺牲了同步消息收发的响应时延(因为批量和异步的原因,很多时候都是攒一波再发)。
posted @ 2022-03-21 14:40  來福l4ifu  阅读(99)  评论(0编辑  收藏  举报