消息队列一文全解!!!

消息队列的用途是什么?

第一章 消息队列的用途是什么?

第二章 消息重复消费如何避免?

第三章 消息的顺序性可靠性如何保证?

第四章 高可用的消息队列如何搭建?

第五章 消息队列面试题汇总


文章目录


前言

本系列文章将对市面上几种主流的消息队列展开详细介绍和深度剖析,我想不管是日常工作还是面试,消息队列一直都是绕不开的话题,在高并发高可用系统架构模型的时代,消息队列似乎成了各家公司在做技术选型时的首选,那么我想市面上的几种消息队列你一开始接触的时候一定很头疼吧。不管你是刚使用消息队列的新手还是已经使用了很多年的老手,你一定能从本系列文章获得新的收获和经验总结。


一、消息队列是什么?

消息队列是一种在软件系统中广泛应用的通信模式,用于在不同的组件、服务或系统之间传递数据。它基于先进先出(FIFO)的原则,允许生产者将消息发送到队列中,并由消费者从队列中获取消息进行处理,而这两个过程是异步进行的。

具体来说,消息队列通常由三个主要组件组成:

  1. 生产者(Producer):生产者是消息的创建者和发送者,它们负责生成消息并将其发送到消息队列中。生产者可能是应用程序、服务、或者是系统中的其他组件。一旦生产者将消息发送到队列中,它们就可以继续执行其他任务,而无需等待消息被处理。

  2. 消息队列(Message Queue):消息队列是消息传递的中间媒介,它由消息代理(Message Broker)管理。消息队列负责接收、存储和转发消息,并确保消息按照其发送顺序进行处理。消息队列的关键特性之一是持久性,即使在生产者或消费者出现故障时,消息也不会丢失。

  3. 消费者(Consumer):消费者订阅队列中的消息,并负责处理它们。消费者可能是应用程序、服务或系统中的其他组件。一旦消息可用,消费者就可以从队列中获取消息并执行相应的操作。与生产者一样,消费者也是异步执行的,因此它们可以在没有直接通信的情况下处理消息。

消息队列的工作原理是通过解耦生产者和消费者之间的通信,实现了系统中不同组件之间的松耦合。这种松耦合使得系统更易于扩展、维护和升级,并提高了系统的可靠性和灵活性。

除了上述的基本组件外,消息队列还可能具有其他功能,例如消息的路由、消息的持久性、消息的优先级等。这些功能使得消息队列能够满足各种不同的业务需求,并在各种应用场景中得到广泛应用,如微服务架构、事件驱动架构、任务队列、日志处理等。

二、为什么使用消息队列?

从上述介绍我们能够理解为啥这么多公司喜欢用消息队列了,因为它真的足够强大,三个比较核心的点,也是我们经常聊到的就是异步削峰解耦。

当谈到消息队列时,常常从异步通信、削峰填谷和解耦三个角度来说明其重要性和应用价值。让我们逐个角度来举例说明:

1. 异步通信

消息队列允许生产者和消费者之间进行异步通信,这意味着生产者在将消息发送到队列后,不需要等待消费者立即处理消息,而是可以继续执行其他任务。这种异步通信有助于提高系统的响应速度、吞吐量和性能。

举例 :假设一个电子商务网站的订单处理系统。当用户下单时,系统不需要立即处理订单支付、库存管理和发货等操作,而是可以将订单信息发送到消息队列中。然后,各个后台服务可以异步地从队列中获取订单消息并进行相应的处理。这种异步通信可以帮助网站应对高并发订单,同时保持系统的稳定性和可靠性。

如果采用串行的调用方式那么会对用户的体验影响很大,用户会觉得你这个系统真的慢死了,但是如果改成通过消息队列的方式,那么会大大提升用户的体验,减少很多投诉。

2. 削峰填谷

消息队列还可以帮助平衡系统的负载,即在高负载时削峰,低负载时填谷。当系统面临突发性的高流量时,消息队列可以暂时存储请求,以防止系统过载崩溃。而在低流量时,消费者可以按照自己的处理能力逐步处理消息,从而保持系统的稳定性和可靠性。

举例 :考虑一个社交媒体平台的消息推送系统。在特定的事件(如热门话题、重要公告等)引发大量用户互动时,系统可能会收到大量的消息推送请求。通过使用消息队列,系统可以将这些消息暂时存储起来,并根据推送服务的处理能力逐步发送消息,从而避免因突发流量而导致的系统崩溃。

因为正常情况下系统的承受能力是有限的,这种大流量的突然出现,确实很可能导致系统崩溃,而用mq去做一次中转,会极大的减轻系统压力,可参考下图。

3. 解耦

消息队列可以帮助解耦系统中的各个组件,降低组件之间的依赖性,使系统更易于扩展、维护和升级。通过将组件之间的通信交由消息队列来处理,组件之间不再直接相互调用,而是通过消息进行间接通信,从而实现了松耦合。

举例:想象一个在线支付系统,其中包括订单处理、支付处理和库存管理等组件。通过使用消息队列,这些组件之间可以通过消息进行通信,而不需要直接相互调用。例如,当用户下单时,订单处理组件将订单信息发送到消息队列中,支付处理组件可以异步地从队列中获取订单信息并处理支付,而库存管理组件也可以根据订单信息更新库存。这种解耦方式使得各个组件可以独立开发、测试和部署,同时降低了系统的复杂性和耦合度。

三、市面上常用消息队列对比

ActiveMQ、RabbitMQ、RocketMQ、Kafka 有什么优缺点?

特性 ActiveMQ RabbitMQ RocketMQ Kafka
单机吞吐量 万级,比 RocketMQ、Kafka 低一个数量级 同 ActiveMQ 10 万级,支撑高吞吐 10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
可用性 高,基于主从架构实现高可用 同 ActiveMQ 非常高,分布式架构 非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可
时效性 ms 级 微秒级,这是 RabbitMQ 的一大特点,延迟最低 ms 级 延迟在 ms 级以内
消息可靠性 有较低的概率丢失数据 基本不丢 经过参数优化配置,可以做到 0 丢失 同 RocketMQ
社区支持 MQ 领域的功能极其完备 基于 erlang 开发,并发能力很强,性能极好,延时很低 MQ 功能较为完善,还是分布式的,扩展性好 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

总结

这些消息队列我基本都有使用过,就目前来看ActiveMq已不建议大家继续使用了,一是比较古老,虽然功能比较完备,但现成的社区没有其他几个完备,遇到问题解决起来会比较棘手。另外RabbitMq和RocketMq,如果没有极高的并发要去我觉得RabbitMq可能更容易上手,社区也比较完善,像kaffa 这个就更不用说了,配合大数据系统来处理一下采集任务会非常给力,谁用谁知道。

相关推荐
小黄编程快乐屋1 小时前
各个排序算法基础速通万字介绍
java·算法·排序算法
材料苦逼不会梦到计算机白富美3 小时前
贪心算法-区间问题 C++
java·c++·贪心算法
羚羊角uou4 小时前
【C++】list模拟实现(详解)
开发语言·c++
Peter_chq4 小时前
【计算机网络】多路转接之select
linux·c语言·开发语言·网络·c++·后端·select
小小李程序员7 小时前
LRU缓存
java·spring·缓存
cnsxjean7 小时前
SpringBoot集成Minio实现上传凭证、分片上传、秒传和断点续传
java·前端·spring boot·分布式·后端·中间件·架构
CRMEB-嘉嘉7 小时前
如何优化 PHP 性能?
开发语言·php
hadage2337 小时前
--- stream 数据流 java ---
java·开发语言
Want5957 小时前
Python绘制太极八卦
开发语言·python