Java分布式:消息队列(Message Queue)
引入消息队列
消息,是服务间通信的一种数据单位,消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。队列,是一种常见的数据结构,它是保存消息的容器。那么消息队列就是以消息为基本单位的优先队列。
借助消息队列,系统的不同部分可相互通信并异步执行处理操作。消息队列提供一个临时存储消息的轻量级缓冲区,以及允许软件组件连接到队列以发送和接收消息的终端节点。这些消息通常较小,可以是请求、恢复、错误消息或明文信息等。
为什么使用消息队列
链式调用是我们写程序时候的一般流程,为了完成一个整体功能,会将其拆分为多个函数或子模块,比如A模块调用B,B模块调用C,C模块调用D。但在大型分布式应用中,系统间的RPC交互繁杂,一个功能背后要调用上百个接口并非不可能,这种架构有如下几个劣势:
- 接口之间耦合严重,每增加一个下游功能,都需要对上游的相关接口进行改造。
- 面对大流量并发时,容易被冲垮。每个接口模块的吞吐能力是有限的,大流量数据容易冲垮服务。
- 性能问题。RPC接口基本上是同步调用,整体的服务器遵循“木桶理论”,即链路中最慢的那个接口,直接拖累了整个服务性能。比如A调用B、C和D(三者并行),D花费时间最长,那么A必须要等到D完成才能继续。
MQ解决痛点
消息队列在实际应用中包括如下四个场景:
- 应用耦合:多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败;
- 异步处理:多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间;
- 限流削峰:广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况;
- 消息驱动的系统:系统分为消息队列、消息生产者、消息消费者,生产者负责产生消息,消费者(可能有多个)负责对消息进行处理;
MQ实现原理
服务如何将消息可靠投递到MQ
1.Client发送消息给MQ
2.MQ将消息持久化后,发送Ack消息给Client,此处有可能因为网络问题导致Ack消息无法发送到Client,那么Client在等待超时后,会重传消息;
3.Client收到Ack消息后,认为消息已经投递成功。
MQ如何将消息可靠投递到服务
1.MQ将消息push给Client(或Client来pull消息)
2.Client得到消息并做完业务逻辑
3.Client发送Ack消息给MQ,通知MQ删除该消息,此处有可能因为网络问题导致Ack失败,那么Client会重复消息,这里就引出消费幂等的问题;
4.MQ将已消费的消息删除
原文地址:https://www.cnblogs.com/MrSaver/p/10473700.html
时间: 2024-10-16 01:26:00