《消息队列》专栏介绍
目录
- 《消息队列》专栏介绍
- 专栏导言
- 什么是消息队列呢?
- 应用场景(作用)
- 为什么要用消息队列呢?
- 异步处理
- 削峰填谷
- 举个例子
- 分布式消息队列的优势
- 应用解耦优点
- 发布订阅优点
- 分布式消息队列应用场景
- 不同消息队列的对比
- 为什么需要开一个专栏来将消息队列
- 关于更新
专栏导言
在当今快节奏的数字化世界中,实时性和可靠性是现代软件开发中的关键词。为了满足用户对即时反馈和高性能的需求,开发人员需要寻找一种高效的通信机制。而消息队列作为一种强大的解决方案,正变得越来越受欢迎。
想象一下,你正在使用一个电商应用程序,下单后希望立即收到订单确认。但是,如果应用程序处理订单的过程变得非常耗时,你可能会感到沮丧。这就是消息队列的用武之地。通过将任务异步处理,应用程序可以立即发送订单确认消息给你,然后在后台处理订单,而不会对用户体验产生任何延迟。
我们现在假设一个开发情景:如果你的系统功能越来越多,长耗时的任务越来越多,系统会越来越复杂,当然我们可以开线程池来解决(我会单独写一篇博客来将JUC线程池的实现),但是线程池是有缺陷的,他只能通过单机部署,如果我们用户量大,改为分布式,多台服务器部署(假设有m台),每个服务器都需要有n个线程,那就需要m*n个线程,会超出服务的限制,资源也会出现抢占。
那么如何解决呢?
- 服务拆分(应用解耦):其实我们可以把长耗时、消耗很多的任务把它单独抽成一个程序,不要影响主业务。
- 解决方案:可以有一个中间人,让中间人帮我们去连接两个系统(比如核心系统和智能生成业务)
什么是消息队列呢?
-
简单来说,消息队列是一种允许应用程序之间异步通信的机制。它通过解耦生产者和消费者之间的直接依赖关系,实现了高度可扩展性和灵活性。
消息队列的工作原理很简单:生产者将消息发送到队列中,然后消费者从队列中获取消息并进行处理。这种异步的方式允许生产者和消费者在不需要实时交互的情况下进行独立的操作。这种解耦能力使得消息队列在许多场景下非常有用,例如在分布式系统中进行任务处理、流量控制、日志收集和系统解耦等。未来详细讲解各种场景的使用。
-
通俗易懂一些,消息队列就是存储消息的队列。他是一种在应用程序之间传递消息的通信机制。它类似于实际世界中的一个邮箱系统,发送者将消息放入消息队列,接收者从队列中获取消息进行处理。这种异步的方式可以提高系统的性能和可靠性,因为发送者和接收者可以独立地进行操作,并且不需要直接相互依赖。
消息队列允许不同的应用程序、服务或组件之间解耦,它们可以独立地进行伸缩和维护。消息队列还提供了可靠性和持久性的保证,因为消息可以在发送时进行持久化,并且在接收者处理之前可以进行多次尝试。
-
消息队列包含的关键词:存储、消息、队列
- 存储:存储数据
- 消息:某种数据结构:比如字符串、对象、二进制、JSON等等
- 队列:一种先进先出的数据结构
应用场景(作用)
在多个不同的系统、应用之间实现消息的传输(也可以存储)。不需要考虑传输应用的编程语言、系统、框架等等。
例如:可以让Java开发的应用发消息,让PHP开发的应用收消息,这样就不用把所有代码写到同一个项目里 (应用解耦)
为什么要用消息队列呢?
使用消息队列有以下几个主要原因:
- 解耦和提高系统可靠性:消息队列提供了解耦的方式,发送方和接收方之间不直接进行通信,通过消息队列中转。这样,即使其中一个组件或者系统出现故障,不会影响到整个系统的正常运行。
- 异步处理和提高系统性能:消息队列可以使发送方和接收方异步处理消息。发送方将消息发送到队列中后,不需要等待接收方立即处理,而是可以继续处理其他任务。这样可以提高系统的性能和响应速度。
- 缓冲和流量控制:消息队列可以作为缓冲区,用于处理流量峰值。当系统面临突发的请求量增加时,消息队列可以缓冲请求并逐渐处理,避免系统过载。
- 同步数据:在分布式系统中,不同组件或者系统之间可能需要共享数据。通过消息队列可以实现数据的同步和共享,保证各个组件之间的数据一致性。
- 扩展和灵活性:使用消息队列可以通过增加消费者来实现系统的扩展性,并且消费者可以根据需求灵活地进行扩缩容。这样可以根据实际需求进行系统的调整和优化。
异步处理
生产者发送完消息之后,可以继续去忙别的,消费者想什么时候消费都可以,不会产生阻塞。
削峰填谷
先把用户的请求放到消息队列中,消费者(实际执行操作的应用)可以按照自己的需求,慢慢去取。
举个例子
- 没有使用消息队列:12点时来了10万个请求,原本情况下,10万个请求都在系统内部立刻处理,很快系统压力过大就宕机了。
- 使用消息队列:把这10万个请求放到消息队列中,处理系统以自己的恒定速率(比如每秒1个)慢慢执行,从而保护系统、稳定处理。类似于管道一样流水式处理。
分布式消息队列的优势
在如今的后台开发中,最常用的一种消息队列就是分布式消息队列了,也是效率最高的,因此本专栏重点讲解分布式消息队列。
分布式消息队列是消息队列的一种。传统的消息队列通常在单个节点上运行,而分布式消息队列可以在多个节点上分布运行,实现更高的吞吐量和可伸缩性。它可以用于解耦、异步通信和扩展系统等方面的应用。常见的分布式消息队列包括 Apache Kafka、RabbitMQ、ActiveMQ 等。
- 数据持久化:它可以把消息集中存储到硬盘里,服务器重启就不会丢失
- 可扩展性:可以根据需求,随时增加(或减少)节点,继续保持稳定的服务
- 应用解耦:可以连接各个不同语言、框架开发的系统,上这些系统能够灵活传输读取数据
- 发布订阅:它可以使发布者将消息发送到一个或多个订阅者,从而实现解耦、可伸缩性和实时性等优势
- 解耦性:发布者和订阅者之间是松耦合的,彼此不需要直接通信。发布者只需要将消息发布到特定的主题或频道中,而订阅者只需要订阅感兴趣的主题或频道。这种解耦性使得系统中的组件可以独立地进行开发、维护和扩展。
- 可伸缩性:发布订阅模式允许多个订阅者同时接收消息,并且可以动态地添加或移除订阅者。这种可伸缩性使系统能够处理更高的并发量,而不会对性能和可用性产生负面影响。
- 实时性:由于发布订阅模式支持多个订阅者同时接收消息,可以更快地将消息传递给订阅者。这种实时性使系统能够实现即时的数据传输和处理,适用于需要快速响应的场景。
- 可靠性:分布式消息队列通常提供了消息持久化的机制,可以将消息存储到磁盘上,确保消息不会丢失。即使消费者出现故障,稍后再启动时也可以继续接收之前未处理的消息。
应用解耦优点
不使用消息队列时:
把所有的功能都放在同一个项目中,调用多个子功能时,一个环节错,整个系统就出错
使用了消息队列进行解耦:
- 一个系统挂了,不影响另一个系统:如果发货系统挂了,但是不影响到库存系统进行扣减
- 系统挂了并恢复后,仍然可以从消息队列当中取出消息,继续执行业务逻辑
- 只要发送消息到队列,就可以立刻返回,不用同步调用所有系统,性能更高
订单系统只要将消息发送到消息队列,即可返回,并不需要调用其他的系统,而其他的系统只要从消息队列中获取到消息。
发布订阅优点
发布订阅优势图解:
如果一个非常大的系统要给其他子系统发送通知,最简单直接的方式是大系统直接依次调用小系统
比如QQ:使用QQ来关联了很多应用的消息,比如王者、吃鸡、微信等等
这样做存在的问题:
- 每次发通知都要调用很多系统,很麻烦、有可能失败
- 新出现的项目(或者说大项目感知不到的项目)无法得到通知
- 发布的消息不知道哪个系统需要
解决方案:大的核心系统始终往一个地方(消息队列)去发消息,其他的系统都去订阅这个消息队列(读取这个消息队列中的消息)
分布式消息队列应用场景
未来会详细讲解常用的应用场景
- 耗时的场景(异步)
- 分布式系统协作(尤其是跨团队、跨业务协作,应用解耦)
- 强稳定性的场景(比如金融业务:支付、转账,特久化、可靠性、削峰填谷)
- 异步通信:当系统需要在不同模块之间进行异步通信时,分布式消息队列可以提供一种可靠的通信机制。
- 解耦应用:当多个应用或服务之间需要解耦,以降低耦合度、提高灵活性和可维护性时,使用分布式消息队列可以实现解耦。
- 流量削峰:在高峰期或服务器负载高的情况下,分布式消息队列可以将流量平滑分发到不同的消费者上,避免系统过载。(高并发场景、异步、削峰填谷)
- 日志处理:对于大规模的日志处理场景,分布式消息队列可以帮助将日志收集、传输和处理进行解耦,并且可以容错和持久化。
- 事件驱动架构:在事件驱动的架构中,各个组件通过订阅消息实现解耦,以便在事件发生时进行相应的处理。
不同消息队列的对比
主要是参考以下几个技术指标进行选择对应的消息队列来开发
-
吞吐量:IO、并发。(表示单位时间内完成的操作次数、传输的数据量或处理的任务数量)
-
时效性:类以延迟,消息的发送、到达时间
-
可用性:系统可用的比率(比如1年365天宕机1s,可用率大概X个9)
可用性的计算公式是:可用时间 / (总时间 - 计划停机时间)。
总时间 = 365 * 24 * 60 * 60 = 31,536,000 秒。
计划停机时间 = 1 秒 * 365 天 = 365 秒。
可用时间 = 总时间 - 计划停机时间 = 31,536,000 - 365 = 31,535,635 秒。
可用性 = 31,535,635 / 31,536,000 ≈ 0.999988 ≈ 99.9988%。
所以,该系统的可用性为约99.9988%。 -
可靠性:消息不丢失(比如不丢失订单)、功能正常完成
-
吞吐量(Throughput)指的是系统在单位时间内能够处理的请求或传输的数据量。在消息队列中,吞吐量表示系统能够处理的消息数量或传输的数据量。较高的吞吐量意味着系统能够更快地处理请求或传输数据。
* 时效性(Latency)指的是从发出请求到收到响应所经历的时间间隔。在消息队列中,时效性表示从消息被发送到消息被接收和处理的时间。较低的时效性意味着消息能够更快地被传输、接收和处理。
消息队列 | 吞吐量(QPS) | 时效性 | 可用性 | 可靠性 | 优势 | 缺点 | 应用场景 |
---|---|---|---|---|---|---|---|
ActiveMQ | 中等:万级 | 高 | 高 | 中等 | 成熟的JMS支持、简单易学 | 性能相对较低 | 中小型企业应用,可靠的消息传递和事务 |
RabbitMQ | 中等:万级 | 极高(微秒单位) | 高 | 高 | 灵活的路由策略、生态好、时效性高、易学 | 对大吞吐量的支持相对较弱 | 复杂的消息路由和灵活的消息处理、适用于大部分的分布式系统 |
Kafka | 高:十万级 | 高(毫秒以内) | 极高 | 极高 | 高吞吐量和低延迟、可靠性、强大的数据流处理能力 | 复杂性较高,初学者上手难度大 | 大数据流处理,日志收集,实时数据流传输、事件流收集传输等 |
RocketMQ | 高:十万级 | 高(毫秒) | 极高 | 极高 | 可靠性、可用性、吞吐量大、分布式事务支持 | 对复杂性的支持相对不足 | 大规模的分布式应用,高可用性和事务一致性要求 适用于金融、电商等对可靠性要求较高的场景,适合大规模的消息处理 |
ZeroMQ | 中等:万级 | 高 | 高 | 低 | 简单的消息传递机制 | 缺乏对复杂消息路由的支持 | 轻量级异步通信,构建快速分布式系统 |
Pulsar | 高:十万级 | 高(毫秒) | 极高 | 极高 | 可靠性、可用性很高、基于发布订阅模型、新兴技术结构、云原生架构支持 | 部署和运维相对复杂 | 适用大规模数据处理,实时分析,高并发的分布式系统。适合实时分析、事件流处理、IoT数据处理等。 |
Apache InLong (Tube) | 高:十万级 | 高 | 高 | 高 | 数据传输和大数据处理集成 | 社区生态相对较小 | 实时分析,数据集成 |
为什么需要开一个专栏来将消息队列
为什么我们需要开一个专栏来深入探讨消息队列呢?
-
复杂性的增加:
随着软件系统的不断扩展和发展,系统之间的通信变得越来越复杂。传统的同步通信方式已经无法满足现代分布式系统的要求。消息队列通过提供异步通信的能力,将生产者和消费者解耦,从而简化了系统之间的通信。开设专栏可以帮助读者理解消息队列的基本概念和原理,并掌握如何在复杂系统中应用它们。
-
实时性和性能的需求:
随着用户对实时性和高性能的要求不断增加,开发人员需要寻找一种能够提供快速响应和高吞吐量的通信方式。消息队列能够以异步的方式处理任务,从而提高系统的响应速度和整体性能。通过专栏的介绍,读者可以学习如何利用消息队列来满足这些实时性和性能需求。
-
大规模系统的挑战:
在大规模分布式系统中,有效地处理和管理海量的消息是一项巨大的挑战。消息队列提供了分布式消息传递、负载均衡和容错机制,能够应对系统规模的扩展性和可靠性要求。通过专栏的学习,读者可以了解如何应对大规模系统中的消息处理问题,并学习一些最佳实践和经验。
-
应用场景的多样性:
消息队列在各个领域都有广泛的应用,如微服务架构、实时数据处理、日志收集和分析等。开设专栏可以涵盖各种应用场景,并通过具体案例帮助读者理解如何在实际项目中应用消息队列。这将帮助读者掌握不同领域中消息队列的实现方式和技巧。
-
技术知识的普及:
消息队列是一项复杂的技术,对于初学者来说可能有一定的学习曲线。通过开设专栏,我们可以以通俗易懂的方式介绍消息队列的概念和原理,并提供详细的实例和图解,帮助读者快速入门和理解关键概念。
关于更新
作者是学生党一枚,能力有限,本着学到哪里更新到哪里的原则。因此我所更新到专栏的知识,一定是我在学习的过程中认为十分重要的,并且自己实践过的内容,也当做我个人的笔记记录。当然也难免会有差错,有问题还请大家及时提出,私信或者评论区交流,谢谢大家!