对消息队列进行深入学习

1.什么是消息队列。

用大白话讲一下

消息队列,就好比是一个快递柜。快递员(生产者)把包裹放进柜子,收件人(消费者)根据自己的时间去取包裹。这样,即使快递员和收件人的时间不对等,也不影响彼此的工作。

1.1消息队列

在这里插入图片描述
消息队列是一种进程间通信或同一进程的不同线程间的通信方式,它作为一个消息容器,用于在发送者和接收者之间传送消息。

比如,A 进程要给 B 进程发送消息,A 进程把数据放在对应的消息队列后就可以正常返回了,B 进程需要的时候再去读取数据就可以了。同理,B 进程要给 A 进程发送消息也是如此。
消息队列可以视为分布式系统中的重要组件,它主要用于解耦、异步处理和流量削峰等场景。其核心概念包括生产者(发送者)、消费者(接收者)和消息本身。生产者将消息放入队列中,而消费者从队列中取出并处理这些消息。

在实际应用中,消息队列常用于处理高并发和大数据量的场景,例如在电子商务平台的秒杀活动中,通过使用消息队列来缓冲大量的订单请求,从而避免后端系统因瞬时流量过大而崩溃。这种缓冲作用也被称为"流量削峰"。

此外,**消息队列还广泛应用于异步处理场景,通过将耗时操作(如发送邮件、处理复杂计算等)异步执行,可以提高系统的响应速度和整体性能。**例如,在一个电商下单系统中,用户下单后需要执行多个后续操作(如扣减库存、通知配送等),这些操作可以并行处理,从而缩短总处理时间。

我自己写的项目中就用到了消息队列。
在这里插入图片描述
同步是阻塞模式,异步是非阻塞模式。

1.1.1同步的理解

同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
同步就相当于是 当客户端发送请求给服务端,在等待服务端响应的请求时,客户端不做其他的事情。当服务端做完了才返回到客户端。这样的话客户端需要一直等待。用户使用起来会有不友好。

1.1.2异步的理解

异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
异步就相当于当客户端发送给服务端请求时,在等待服务端响应的时候,客户端可以做其他的事情,这样节约了时间,提高了效率。

异步虽然好 但是有些问题是要用同步用来解决,比如有些东西我们需要的是拿到返回的数据在进行操作的。这些是异步所无法解决的。

1.2消息传递与消息队列

消息传递和消息队列是两个相关但不同的概念。

消息传递是一种通信模式,指在计算机系统中,不同组件之间通过发送和接收消息来进行通信。消息可以是简单的数据,如文本或对象。消息传递可以基于共享内存或直接的消息发送,分为同步和异步两种形式。

消息队列是实现消息传递的一种具体机制。它是一个先进先出(FIFO)的数据结构,用于存储和转发消息,直到它们被合适的接收者处理。消息队列能够实现消息的持久化、保证消息顺序和增强传输的可靠性。

消息队列具有解耦、异步处理、削峰填谷等特点,极大地提高了系统的灵活性和稳定性。然而,使用消息队列也带来了系统复杂性增加和管理成本上升的挑战。

消息传递更侧重于通信的模式,而消息队列则是实现这种通信模式的具体技术手段。在实际应用中,根据系统需求合理选择和设计消息传递方式至关重要

2. 消息队列应用场景

消息队列在现代分布式系统中有着广泛的应用场景,从异步处理、应用解耦、流量削峰、日志处理、消息通讯、延时任务、广播消费到分布式事务,无不体现了其在提高系统性能、稳定性和可扩展性方面的重要作用。

2.1 异步处理

用户注册与邮件短信通知:用户注册后通常需要发送验证邮件和短信。传统的做法是串行或并行处理这些任务,但这样会显著影响用户体验。通过引入消息队列,将邮件和短信写入队列后立即返回操作结果,从而大幅提高响应速度和系统吞吐量。
订单处理与物流分解:在电商系统中,创建订单后需要通知库存系统并安排物流配送。这些操作如果同步进行,会导致整个订单处理时间延长。引入消息队列后,订单系统只需将包含订单信息的消息发布到队列中,而库存系统和物流系统作为消费者独立处理这些信息。

2.2 流量削锋

秒杀活动:大规模促销活动如秒杀、团购等,会在特定时间内产生巨大的流量,可能压垮后端服务。通过在前端加入消息队列进行缓冲,可以将突发的请求先保存在队列中,再逐步消化,从而保护后端系统不被瞬时流量压垮。
分批次处理请求:对于预计会产生大量并发请求的操作,可以先将这些请求存储在消息队列中,然后由后端服务按照实际处理能力分批次消费这些请求,确保系统的稳定运行。

2.3 应用解耦

订单系统与库存系统解耦:在没有消息队列的情况下,订单系统通常需要直接调用库存系统的接口来减少库存。这不仅增加了系统间的耦合度,还可能导致因库存系统不可用而无法创建订单的情况。引入消息队列后,订单系统只需将订单信息写入队列,库存系统订阅该消息进行处理,从而实现解耦。
跨系统数据同步:例如,在微服务架构中,不同的服务可能需要共享某些数据或事件。通过消息队列,一个服务可以发布事件到队列中,其他服务订阅这些事件并作出相应处理,避免了服务之间的直接依赖。

2.4 日志处理

集中式日志收集:在大型分布式系统中,各个服务产生的日志信息可以通过消息队列统一收集和处理。例如,使用Kafka等消息队列系统收集各个服务的日志,再通过ELK(Elasticsearch, Logstash, Kibana)堆栈进行集中分析和可视化。
实时监控与告警:通过消息队列传输各类系统指标和日志,可以利用流处理技术实时监控并生成告警信息,提升系统运维的及时性。

2.5 消息通讯

点对点通讯:消息队列支持点对点的消息传递模式,适用于双向通信场景,如客户端与服务器之间的请求与响应。
聊天室通讯:利用发布-订阅模式,可以实现聊天室功能。多个客户端订阅同一主题,服务器将消息发布到该主题,所有客户端均能收到。

2.6 延时任务

订单超时取消:用户下单后一定时间内未支付,系统需自动取消订单。通过消息队列的延时投递功能,可以在设定的时间后将消息送达消费者,以执行取消订单的操作。
定期任务:某些需要定时执行的任务,比如每日统计、清理缓存等,也可以通过消息队列的延时消息功能来轻松实现。

2.7 广播消费

推送通知:在专车服务中,派单系统需要将订单信息推送给附近的司机。通过消息队列的广播模式,可以确保每个在线司机都能收到通知。
缓存同步:当数据变更频繁且需要在多个服务间同步时,可以利用消息队列的广播消费机制,将最新数据分发到各个服务,保持缓存的一致性。

2.8 分布式事务

最终一致性保证:在电商交易等涉及多个子系统协同工作的复杂业务流程中,通过消息队列记录和协调各个步骤,可以保证分布式事务的最终一致性。
补偿操作:一旦某个步骤失败,可以利用消息队列中的事务消息来进行回滚或者补偿操作,确保系统的稳定和数据的准确性。

3. 主流消息队列

当前使用较多的消息队列有RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ等。我这里简单介绍一下RabbitMQ和Kafka。

3.1 RabbitMQ

RabbitMQ 就像一个快递服务。快递员(生产者)把包裹送到快递站,快递站负责存储并最终将包裹转发给收件人(消费者)。在这个过程中,快递站不关心谁送来的或者谁取走的,只负责存储和转发。

RabbitMQ 是一个基于高级消息队列协议(AMQP)的开源消息中间件,主要用于在应用之间进行异步通信。MQ就是message queue消息队列。

AMQP协议(Advanced Message Queuing Protocol—高级消息队列协议)
它由摩根大通集团联合其他公司共同设计。是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。

3.1.1 RabbitMQ工作原理

原理图

RabbitMQ 的工作原理主要涉及生产者、消费者、交换机、队列和绑定等组件。通过高级消息队列协议(AMQP)进行通信,以实现异步通信和应用解耦。以下是详细步骤:

生产者(Producer):生产者负责创建并发送消息到RabbitMQ服务器。这些消息可以包含各种类型的数据,如JSON或XML。生产者首先与RabbitMQ建立连接,创建一个信道(Channel),然后声明一个或多个队列,并通过信道将消息发送到这些队列中。
交换机(Exchange):交换机接收来自生产者的消息,并根据预定义的路由规则将消息转发到一个或多个队列。RabbitMQ提供了多种类型的交换机,如直连(direct)、主题(topic)、扇出(fanout)和头部(headers)交换机,每种类型都有自己的路由策略。
队列(Queue):队列是消息存储的中心。交换机将消息路由到队列,消费者则从队列中获取消息进行处理。队列中的消息遵循先进先出(FIFO)的原则,消费者按照消息进入队列的顺序进行消费。消费者可以订阅一个或多个队列,并从这些队列中接收消息。
绑定(Binding):绑定定义了交换机与队列之间的关系以及消息从交换机到达队列的路由规则。通过绑定,可以确保特定类型的消息被路由到特定的队列中。
消费者(Consumer):消费者连接到RabbitMQ服务器,创建一个信道,并订阅一个或多个队列以从中接收消息。当消费者成功处理一条消息后,会向RabbitMQ服务器发送确认消息(acknowledge),确认之后,RabbitMQ会从队列中删除该消息。
消息确认与持久化:为保证消息可靠性,RabbitMQ支持消息确认机制。消费者必须发送确认消息给RabbitMQ,否则RabbitMQ会认为消息未被处理并可能重新发送给其他消费者。同时,为保持消息持久性,可以将交换机、队列和消息都设置为持久化,这样在RabbitMQ服务器重启时,这些消息不会丢失。
通过以上步骤,RabbitMQ实现了高效、可靠的消息传递。这种架构不仅解耦了应用之间的依赖关系,还提供了灵活的消息路由和分发机制。

3.1.2 优点

由于 erlang 语言的高并发特性,性能较好;吞吐量到万级,MQ 功能比较完备、健壮、稳定、易用、跨平台、支持多种语言如Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持 AJAX 文档齐全;开源提供的管理界面非常棒,用起来很好用,社区活跃度高;更新频率相当高。

3.1.3 缺点

商业版需要收费,学习成本较高。

3.1.4 选用场景

结合 erlang 语言本身的并发优势,性能好时效性微秒级,社区活跃度也比较高,管理界面用起来十分方便,**如果你的数据量没有那么大,中小型公司优先选择功能比较完备的 RabbitMQ。**数据大就选kafka。

3.2 Kafka

Kafka是一个分布式的消息队列系统,就像是一个大型的留言板,它能够让不同的用户(或程序)在上面发帖(发送消息)和浏览帖子(接收消息)。

在Kafka中,消息被分成一个个主题(Topic),就像是留言板上的不同板块。用户可以向特定的主题发送消息,也可以订阅某个主题以接收消息。

大数据的杀手锏,谈到大数据领域内的消息传输,则绕不开 Kafka,这款为大数据而生的消息中间件,以其百万级 TPS 的吞吐量名声大噪,迅速成为大数据领域的宠儿,在数据采集、传输、存储的过程中发挥着举足轻重的作用。目前已经被 LinkedIn,Uber, Twitter, Netflix 等大公司所采纳。

3.2.1 优点

性能卓越,吞吐量高,单机写入 TPS 约在百万条/秒,时效性 ms 级,可用性非常高;其次 kafka 是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据导致服务不可用,消费者采用 Pull 方式获取消息,消息有序,通过控制能够保证所有消息被消费且仅被消费一次。此外 kafka 有优秀的第三方 Kafka Web 管理界面 Kafka-Manager,在日志领域比较成熟,被多家公司和多个开源项目使用;最后 kafka 在功能支持方便面它功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用。

3.2.2 缺点

Kafka 单机超过 64 个队列/分区,Load 会发生明显的飙高现象,队列越多,load 越高,发送消息响应时间变长,使用短轮询方式,实时性取决于轮询间隔时间,消费失败不支持重试;支持消息顺序,但是一台代理宕机后,就会产生消息乱序,社区更新较慢;
选用场景:Kafka 主要特点是基于Pull 的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输,适合产生大量数据的互联网服务的数据收集业务。大型公司建议可以选用,如果有日志采集功能,肯定是首选 kafka 了。

Kafka 是一个分布式流式处理平台。这到底是什么意思呢?

流平台具有三个关键功能:

  1. 消息队列:发布和订阅消息流,这个功能类似于消息队列,这也是 Kafka 也被归类为消息队列的原因。
  2. 容错的持久方式存储记录消息流: Kafka 会把消息持久化到磁盘,有效避免了消息丢失的风险。
  3. 流式处理平台: 在消息发布的时候进行处理,Kafka 提供了一个完整的流式处理类库。

Kafka两大应用场景:

  1. 消息队列 :建立实时流数据管道,以可靠地在系统或应用程序之间获取数据。
  2. 数据处理: 构建实时的流数据处理程序来转换或处理数据流。

和其他消息队列相比,Kafka的优势在哪里?

我们现在经常提到 Kafka 的时候就已经默认它是一个非常优秀的消息队列了,我们也会经常拿它跟 RocketMQ、RabbitMQ 对比。我觉得 Kafka 相比其他消息队列主要的优势如下:

  1. 极致的性能 :基于 Scala 和 Java 语言开发,设计中大量使用了批量处理和异步的思想,最高可以每秒处理千万级别的消息。
  2. 生态系统兼容性无可匹敌 :Kafka 与周边生态系统的兼容性是最好的没有之一,尤其在大数据和流计算领域。

相关推荐

  1. 进程间通信学习消息队列

    2024-07-18 21:46:02       55 阅读
  2. Mapper.xml文件进行深入学习

    2024-07-18 21:46:02       36 阅读
  3. C#如何进行深度学习行人进行识别?

    2024-07-18 21:46:02       21 阅读
  4. 常见消息队列及其

    2024-07-18 21:46:02       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 21:46:02       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 21:46:02       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 21:46:02       57 阅读
  4. Python语言-面向对象

    2024-07-18 21:46:02       68 阅读

热门阅读

  1. APP开发者选择苹果企业签名的理由是什么?

    2024-07-18 21:46:02       21 阅读
  2. 负载均衡轮询逻辑

    2024-07-18 21:46:02       19 阅读
  3. swift小知识点(二)

    2024-07-18 21:46:02       18 阅读
  4. Redis常见阻塞原因

    2024-07-18 21:46:02       22 阅读
  5. Pandas库学习之DataFrame.replace()函数

    2024-07-18 21:46:02       21 阅读
  6. ros2--插件

    2024-07-18 21:46:02       26 阅读
  7. 探索 Flask:从入门到精通的完整学习指南

    2024-07-18 21:46:02       21 阅读
  8. antd使用踩坑记录

    2024-07-18 21:46:02       19 阅读
  9. 数组 59.螺旋矩阵Ⅱ

    2024-07-18 21:46:02       22 阅读
  10. 无人机反制:车载侦测干扰一体设备技术详解

    2024-07-18 21:46:02       21 阅读