消息队列

消息队列原理以及各种消息中间件
帅旋
关注
充电
IT宅站长,技术博主,架构师,全网id:arthinking。

消息队列那么多,为什么建议深入了解下RabbitMQ?

发布于 2021-10-12 | 更新于 2024-05-16

image-20211010214319029

你为啥要在项目中选择xxx消息中间件?

提起消息队列,也许你的脑海里会不自觉地蹦出好多概念:JMS、Kafka、RocketMQ、AMQP、RabbitMQ、ActiveMQ、Pulsar、Redis Stream…如果你的项目中恰好用到了其中的一个消息中间件,那么你出去面试或者与同事交流技术的时候,对方很大概率会问你:为啥要选择xxx消息中间件?

如果你刚好只了解你正在用的消息中间件,那么你只能回答:因为只会xxx…

image-20211006183323991

不…这绝对不是你想要的结局!在对方准备看你的笑话之前,你也许可以主动发起还击,把所有的框架的诞生背景、优缺点,适用场景等都说一遍,从概念到原理,从特性到源码。在说完了之后,为了不让对方感觉到尴尬,你应该故意停顿片刻,暗示对方自己不想再聊这个话题了,好让对方有喘息的机会,让他趁早切换话题,给他一个台阶下。

image-20211006183625852

为了让自己能有如此实力,你务必要对这些常见的消息中间件有比较深入的了解。

我们先来看看这些技术的发展史。

MQ技术发展史

如下图所示:

image-20211010220759711

  • **操作系统中的消息队列:**在操作系统里面,我们可以通过消息队列实现两个或多个进程/线程之间的异步通信,发送方和接收方不需要同时与消息队列交互。放置在队列中的消息会一直存储,直到接收者取回它们。消息队列对可以在单个消息中传输的数据大小和队列能够存储的消息数量上限有隐式或显式限制;
  • **TIB:**1983年,一位来自孟买的工程师Vivek Ranadive提出了一个问题:为什么没有通用的软件总线–一种通信系统,可以将信息从一个应用程序传递到另一个应用程序呢?最终,Vivek Ranadive创办了Teknekron公司,在1985年实现了第一个消息中间件:Teknekron的The Information Bus(TIB);
  • **MQSeries:**TIB受到了企业的欢迎,同时这也被IBM看在眼里,于是他们决定研发自己的消息队列软件。最终,在1993年,IBM推出了面向消息中间件的产品,MQSeries,2002年更名为WebSphereMQ,2014年更名为IBM MQ;
  • **MSMQ:**这么好的发财机会怎么能错过呢,于是微软也加入了竞争队伍,并在1997年发布了自家的消息中间件产品:MSMQ;
  • **JMS:**这些巨头推出的消息中间件价格昂贵,一般只应用于大型组织机构。并且,由于商业壁垒,MQ厂商们只关注于应用互通的问题,而不会去考虑创建标准来实现不同的MQ产品之间的互通。为了打破这个壁垒,于是JMS诞生了;
    • JMS,即Java消息服务(Java Message Service),是由Sun公司早期提出的消息标准,为Java提供统一的消息操作,是Java平台中关于面向消息中间件的接口;
    • JMS是一种与厂商无关的API,类似于JDBC(Java Database Connectivity),用来访问消息系统和收发消息的编程API;
    • 不过JMS毕竟是在真实的消息中间件API上面做了一层适配,各个消息中间件的实现仍旧是没有一个规范,最终会暴露出问题,使得程序更加混乱与脆弱。此刻,我们需要的是一种消息通信标准;
  • **AMQP:**在2004至2006年,摩根大通在着手设计AMQP,最终,与其他公司(Cisco, Red Hat, iMatix等)成立了AMQP工作组,越来越多的公司参与进来,最终在2006年制定了AMQP的公开标准,由此,AMQP登上了历史的舞台,大家可以基于此标准来实现消息中间件,不受任何开发语言、产品等的条件限制;
  • **RabbitMQ:**RabbitMQ最初就是一个实现了AMQP的消息中间件,本文我们会详细介绍这个家伙;
  • Kafka: Kafka是一种分布式流式系统,被设计为能够作为一个统一平台来处理大型公司可能拥有的所有实时数据馈送。为此,它必须具有高吞吐量才能支持大容量事件流,例如实时日志聚合;
    • RabbitMQ是基于队列和交换器的消息中间件,而Kafka是使用分区事务日志来实现存储层的分布式流式系统
    • Kafka不存在队列,而是按照主题存储记录集,并且为每个主题维护一个消息分区日志;
    • Kafka中消费者自己维护消息的消费偏移量,支持持久订阅和临时订阅(重启后丢失偏移);
    • Kafka中的消息是按照预设的时间进行持久化的,而不是根据消费状态;
    • Kafka的设计之初就考虑到了高性能,通过以下方式实现:
      • 利用分区实现并行处理;
      • 使用磁盘顺序写,以及充分利用页缓存;
      • 零拷贝技术;
      • 批处理技术,数据压缩等;
  • **RocketMQ:**随着阿里巴巴的电商业务不断发展,需要一款更高性能的消息中间件,RocketMQ就是这个业务背景的产物。RocketMQ是一个分布式消息中间件,具有低延迟、高性能和可靠性、万亿级别的容量和灵活的可扩展性,它是阿里巴巴于2012年开源的第三代分布式消息中间件。RocketMQ经历了多年双十一的洗礼,在可用性、可靠性以及稳定性等方面都有出色的表现。值得一提的是,RocketMQ最初就是借鉴了Kafka进行改造开发而来的,所以熟悉Kafka的朋友,会发现RocketMQ的原理和Kafka有很多相似之处;
  • **Pulsar:**在Yahoo,为了追求大集群多租户、稳定可靠的 IO 服务质量、百万级 Topic、跨地域复制等需求,Pulsar 应运而生,以弥补Kafka在这方面的不足,Pulsar的优点:
    • 应用场景:Pulsar 对用户来说提供了统一的消息模型,可以满足各种MQ;
    • 架构优势:有存储计算分离的云原生架构的优势,使用BookKeeper作为Pulsar的存储层。在 Broker 层不存储任何数据,具有更高的可用性、更灵活的扩容和管理,避免数据的 reblance 和 catch-up;
    • 社区活跃度:Pulsar 用户和贡献者数量也在快速增加…

Pub/Sub模式以及第一个消息中间件诞生的故事

1985年在高盛,Ranadive 找到了他的第一个客户,并确定了他的软件总线要解决的问题:金融交易。

当时,一个交易员的摊位挤满了不同的终端,用于提供交易员完成工作所需的每种类型的信息。 Teknekron 看到了替换所有这些终端及其应用程序的机会:通过Ranadive软件总线取而代之,只需保留一个工作站即可,其显示程序可以作为消费者插入Teknekron软件总线,并允许交易者“订阅”其想要查看的信息。 Pub/Sub 诞生了,世界上第一个现代消息队列软件也诞生了:Teknekron的The Information Bus(TIB)。

而RabbitMQ作为传统的消息中间件,被大量应用于各种古老的项目,你第一个要拿下的就是它了,本文将带您从以下各个方面了解RabbitMQ相关知识:

  • 什么是AMQP?
  • 常见的交换机类型有哪些?
  • 如何实现消息的持久化?
  • RabbitMQ的连接复用有啥优势?
  • RabbitMQ的消息ACK机制是如何实现的?
  • RabbitMQ消息持久化机制性能如何?
  • 如何避免消费过载的问题?
  • 如何提高手动ACK签收的效率?
  • 什么时候需要让消息重回队列?
  • 如何保证消息的顺序消费?
  • 如何实现可靠的消息投递?

关于其他的消息中间件,我会在下篇文章中继续给大家分享。

RabbitMQ是一种使用Erlang语言编写的开源的消息中间件,最初实现了AMQP(高级消息队列协议),后来通过插件架构进行了扩展,支持STOMP(面向流文本的消息传递协议)、MQTT(MQ遥控传输)等协议。

详细关于RabbitMQ支持的消息协议,参考官网:Which protocols does RabbitMQ support?[1]

更多内容欢迎关注公众号Java架构杂谈,或者我的博客IT宅itzhai.com

RabbitMQ优势

RabbitMQ支持多种客户端,如Python、Java、.NET、C、Ruby等,在易用性、扩展性、高可用性等方面表现都不错,并且可以与SpringAMQP完美整合,API丰富易用。

RabbitMQ程序健壮、稳定、易用,跨平台、支持多种语言,管理界面简单易用,功能全面,文档相对比较齐全,社区活跃。

References


  1. Which protocols does RabbitMQ support?. Retrieved from https://www.rabbitmq.com/protocols.html ↩︎

本文作者: 帅旋

本文链接: https://www.itzhai.com/columns/mq/rabbitmq/advanced-tutorial.html

版权声明: 版权归作者所有,未经许可不得转载,侵权必究!联系作者请加公众号。

×
IT宅

关注公众号及时获取网站内容更新。

请帅旋喝一杯咖啡

咖啡=电量,给帅旋充杯咖啡,他会满电写代码!

IT宅

关注公众号及时获取网站内容更新。