专栏首页后端秒懂消息队列
原创

秒懂消息队列

摘要

作为技术方案最常提到的组件:消息队列,它在我们的程序中起到了重要的作用。异步、解耦、削峰(缓冲)等特性正是我们选择它的原因。本文将会按自己的理解聊一聊消息队列的本质、使用场景、注意事项、以及介绍下主流的消息队列。

一、消息队列是什么?

在使用消息队列之前,我们首先得对它有一个清楚的认知。通常在上下游的通信过程中,我们需要一个载体来传送某一方关心的信息。

比如用户在商城下单成功后,商品信息会被打包成一个对象,发送给物流模块。在这里,物流模块就是上游,而商品信息就是消息。在将对应模块抽象出来后,通过消息这个粘合剂,就能将整条链路连接起来。

上面提及到的上下游模块假设都在同一个进程里,那么消息的存在方式就是内存了;那如果上下游是在两个进程程序或者部署在不同的机器中呢?消息又该以何种方式存储?又该怎么流转呢?

这就是“队列”的作用了,传统的数据结构“队列”表示的是一种先进先出的链表。而这里的“队列”更多的是指兼具存储和路由特性的消息管理器。

至于消息的存储方式可以是临时内存,也可以持久化到文件或数据库中。但消息不会一直存储着,它有属于自己的消费规则,在按一定的规则分发到各个模块后,就会被剔除掉。

秒懂消息队列

二、消息队列的特性与使用

在软件设计里,我们经常要求模块功能遵守单一职责原则,这跟专人专事是一样的道理。但在涉及服务与服务的调用过程中,总会涉及到状态维护、失败重试等跟主流程关联性不强的需求。而这部分功能正是消息队列的强项。

一般的,我们将发送数据给消息队列的功能模块,称之为“生产者”。而最终使用消息的模块,称之为“消费者”。

当生产者成功投递消息后,就不再关心消息的流转了,后续的流程将由消息队列来保证,生产者最多保存下元数据。而为了防止数据丢失,消息队列一般都会提供持久化功能,以便进行重启恢复。

这样一来,即使生产者发送了异常,只要消息队列能正常运行,能继续分发剩余的消息,那消费者就不会空闲下来。

从这,我们也能看出消息队列的解耦作用,让生产者与消费者互不关联。

在解耦的同时,消息队列也提供了一个缓冲地带。当面对高并发高流量到来时,消息并不会直接的打到消费端,它会先在消息队列走一回。只要我们在消息队列里做好把控,那么它就不会成为压倒系统的最后一根稻草。

而市面上的消息队列框架一般都会考虑到这些异常情况,比如提供了流量控制的 RabbitMQ。

在有了消息队列这个中间件之后,我们应该尽可能的将系统设计成异步处理的。比如,前面提到过的下单完成通知与物流发货功能。

三、消息队列的注意事项

尽管有了消息队列的存在,系统服务的联动变得更加的灵活,可拓展性也大大提高。但毕竟引入了第三方组件,这也意味着复杂度增加了。

一致性、幂等性

不管你承不承认,从我们把消息队列抽象出来后,我们的系统就是一个分布式存在了。对于分布式系统,最难的莫过于一致性问题,先有 CAP 原则,后有 BASE 理论,此处本文不会详细说明,大伙感兴趣的可以自己研究下。这里想提及的就是不能单靠消息队列本身来实现消息的可靠性、一致性。还得生产者、消费者一起来完善整条传输链路。

对于生产方来说应该要考虑本地操作+发送消息这一动作的事务特性,当消息发送失败时,本地操作要有回滚动作,或者通过定时校验来达到最终一致状态。

对于消费端来说,要有幂等性的保证。由于网络环境的复杂,我们是无法在一次通信过程中就能确定消息接收情况的。消息队列往往会有重发机制,来防止失败或超时的情况产生。

因此,我们不能简单的认为,消息有且只会出现一次,这是不现实的。

通常的,我们会在消息中添加业务唯一标识,外加状态字段进行事务性的判断修改,来确保业务的一次执行。

顺序性

在同一个进程里想要实现顺序性并不难,只要有一个全局的控制即可。但一般我们的消息队列为了避免单机瓶颈,都会提供集群的部署方式。这种在分布式里考虑顺序性,难度无疑大大提高。

因此对于顺序性的消息需求,我们应该尽可能从业务上重新规划,考虑是否真的有这个必要性。当然,现在流行的消息队列框架也是有提供顺序性功能的,像 Kafka 的 相同 Partition 策略。

常见的消息队列

前面提到过 RabbitMQ、Kafka,它们都是主流的消息队列。常见的还有 ActiveMQ 以及 阿里的 RocketMQ。

RabbitMQ 是用 erlang 语言开发的,实现了高级消息队列协议(AMQP),并且提供了多语言的 SDK 接口,有比较完善的消息转发机制。

Kafka 具有高吞吐高性能的数据处理能力,常用于日志收集,像 ELK 日志分析系统就采用了 Kafka 作为消息队列。

ActiveMQ 是 Apache 出品的消息队列,实现了 Java 消息服务(JMS)协议。是一个成熟的、快速的开源消息组件

RocketMQ 从它的名字就看得出来它的高性能了,当然,由于它是阿里开源的,所以在文档资料方面还是挺有优势的。而且也比较贴近我们中国程序员的开发思维。

上面的消息队列框架大多具备了高可用、高拓展、高性能的特性。个人推荐当然是国产的 RocketMQ 了(◠◡◠)。

总结

消息队列就像我们生活中的中介,引入它是需要付出代价的,但它也确实能让我们更加专注于业务上的开发。而且现在市面上已经有很多成熟可用的开源项目了,借助开源的力量,我们的程序将能够更加的健壮!


感兴趣的朋友可以搜一搜公众号「 阅新技术 」,关注更多的推送文章。

可以的话,就顺便点个赞、留个言、分享下,感谢各位支持!

阅新技术,阅读更多的新知识。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

关注作者,阅读全部精彩内容

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 秒杀场景下的消息队列

    异步处理是提升系统性能的神器,但需要分清同步流程和异步流程的边界,同时消息存在丢失的风险,我们需要考虑如何确保消息一定到达。

    WindCoder
  • 消息队列(一) MySQL实现消息队列

    消息队列(一)MySQL实现消息队列 (原创内容,转载请注明来源,谢谢) 一、概述 消息队列(MessageQueue,通常简称MQ)是一种进程间通信或同一进...

    用户1327360
  • 消息队列-腾讯云消息队列 CKafka

    腾讯云消息队列 CKafka,分布式、高吞吐量、高可扩展性的消息服务,100%兼容开源 Apache Kafka 0.9 0.10

    用户3570397
  • 消息队列

    radaren
  • 消息队列

    一般来说,消息队列是一种异步的服务间通信方式,是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。

    用户4464623
  • 消息队列

    发送者将消息发送给消息队列之后,不需要同步等待消息接收者处理完毕,而是立即返回进行其它操作。消息接收者从消息队列中订阅消息之后异步处理。

    全栈程序员站长
  • 消息队列

    其实就是问问你消息队列都有哪些使用场景,然后你项目里具体是什么场景,说说你在这个场景里用消息队列是什么?

    OwenZhang
  • 【消息队列 MQ 专栏】消息队列之 Kafka

    Kafka 最早是由 LinkedIn 公司开发一种分布式的基于发布/订阅的消息系统,之后成为 Apache 的顶级项目。主要特点如下:

    芋道源码
  • 【消息队列 MQ 专栏】消息队列之 ActiveMQ

    ActiveMQ 是由 Apache 出品的一款开源消息中间件,旨在为应用程序提供高效、可扩展、稳定、安全的企业级消息通信。它的设计目标是提供标准的、面向消息的...

    芋道源码
  • 【消息队列 MQ 专栏】消息队列之 RocketMQ

    RocketMQ 是阿里巴巴在2012年开源的分布式消息中间件,目前已经捐赠给 Apache 软件基金会,并于2017年9月25日成为 Apache 的顶级项目...

    芋道源码
  • 消息队列探秘-RabbitMQ消息队列介绍

    RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现。AMQP 的出现其实也是应了广大人民群众的需求,...

    高广超
  • 消息队列及常见消息队列介绍

    消息队列是分布式系统中重要的组件,在很多生产环境如商品抢购等需要控制并发量的场景下都需要用到。最近组内需要做流水server的选型升级,这里对消息队列及常见的消...

    曾令武
  • 消息队列探秘 – RabbitMQ 消息队列介绍

    RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现。AMQP 的出现其实也是应了广大人民群众的需求,...

    java思维导图
  • 消息队列_RabbitMQ

    神秘的寇先森
  • FreeRTOS 消息队列

    上面这几中方式中, 除了消息通知, 其他几种实现都是基于消息队列。消息队列作为主要的通信方式, 支持在任务间, 任务和中断间传递消息内容。 这一章介绍 Fre...

    orientlu
  • POSIX消息队列

    消息队列是Linux IPC中很常用的一种通信方式,它通常用来在不同进程间发送特定格式的消息数据。

    WindSun
  • 消息队列MQ

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    chenchenchen
  • Rabbitmq---消息队列

    有了消息队列,每一次连接不管是生成消息还是消费消息,都有各自的逻辑与其他逻辑无关--通信解耦

    Java高级架构
  • 消息队列kafka

    在流式计算中,Kafka一般用来缓存数据,Storm通过消费Kafka的数据进行计算。

    超蛋lhy

扫码关注云+社区

领取腾讯云代金券