目录
消息中间件
介绍
中间件
帮助 [应用程序] 与 [其他应用程序/网络/硬件/操作系统] 交互或通信的软件
- 也就是将 具体业务 和 底层逻辑 解耦的软件
- 应用程序只需通过中间件提供的接口进行操作,不需要关心如何实现底层的网络协议、数据存储、事务管理等,具体的访问细节由中间件去补足
- 中间件包含多种类型 -- 数据库中间件 / 消息中间件 / Web中间件(Tomcat,Nginx)
消息中间件
消息中间件指的是一种支持消息传递的中间件技术,它允许应用程序通过异步的、可靠的消息传递在不同的计算平台和操作系统之间交换数据
- 消息中间件支持 点对点(P2P)和 发布/订阅(Pub/Sub)两种通信模式,并能够确保消息的可靠性、顺序和事务性
- 当下主流的消息中间件有RabbitMQ、Kafka、ActiveMQ、RocketMQ等
- 是分布式系统中非常重要的组件,主要用来解决应用耦合、异步通信、流量削峰等问题
点对点(P2P)模型
一个生产者发送消息到一个队列,单个消费者从队列中取出并处理消息
- 消息队列是点对点模式的主要实现形式,生产者与消费者之间通过消息队列解耦,不直接通信,而是通过消息队列进行异步传递
- 常见实现:RabbitMQ、ActiveMQ、IBM MQ等,支持P2P模式
发布/订阅(Pub/Sub)模型
一个发布者发布消息到一个主题,多个订阅者可以接收这些消息
- 同一条消息可以被多个消费者(订阅者)同时处理
- 常见实现:Apache Kafka、RabbitMQ(支持主题的发布/订阅模式)、Google Pub/Sub等
消息队列
消息队列(Message Queue, MQ)是一种数据结构,用于存储消息并按顺序传递消息
- 在实际开发中,"MQ" 广泛用来代指各种基于消息传递机制的中间件系统
为什么分布式系统需要
为什么分布式系统需要消息中间件?不能用 HTTP/RPC/数据库/共享内存 来实现吗?
- 其他方式可以做通信,但消息中间件能把分布式系统做到更稳、更松耦合、更可扩展
- 下面先说明一下,为什么其他方式不行
HTTP / RPC 直连通信
介绍
HTTP/RPC 是同步请求—响应的交互模型:Client向Server发起请求并等待响应,调用线程/任务通常会被阻塞直到响应或超时
- 直连是两端紧紧绑在一起,上游必须等下游
缺点
强耦合
- A依赖B,A 必须知道 B 的地址、接口、版本、可用性
- 若 B 的接口变动或 B 下线,那么A也必须改变
同步阻塞
- 同步请求会占用A的线程/连接资源
- 如果 B 处理较慢或网络延迟高,A 的线程池很快被占满(每个请求对应一个线程)
产生级联故障
- 如果在链式调用A→B→C中,下游卡顿会放大问题,并波及上游
故障传播快
- 同步依赖使得下游的故障立即影响到上游的业务可用性
数据库轮询
介绍
用数据库表作为“消息总线” -- 生产者向表写记录,消费者定时查询(轮询)表并处理未处理记录
缺点
延迟高
轮询间隔决定了最小可见延时
要实时就需要短间隔轮询,造成高负载;要省资源就必须容忍更长延迟
DB 成为瓶颈
大量轮询请求会加重 DB 负担并影响主业务(可能使事务响应变慢)
竞争 & 顺序问题
多个消费者并发轮询要防止重复处理/抢占(需要锁、行级 update、标记机制),这些操作会涉及到事务与锁竞争,进一步降吞吐
可扩展性差
数据库并不是为消息高并发读写设计(尤其是大并发写+读的模式)
共享内存 / 本地文件
介绍
使用操作系统提供的共享内存、管道、消息队列(POSIX IPC)、或本地文件系统来传递消息
缺点
只限单机
跨机器无法直接共享内存或本地文件
扩展性差
要横向扩展(多台机器)必须引入分布式协调/同步机制,反而比直接用专门的消息系统更难实现
管理复杂性
内存/文件并发访问要做同步(锁、信号量),容易出错
于是,下面来说说,为什么分布式系统需要消息队列
消息中间件
加入MQ后,结构变成了 A -> MQ -> B
- 它解决了分布式中的 3 个根本矛盾
解耦
A 完成自己的任务,把消息放到队列里就结束
A不需要关心消费者是否在线,新增/减少也不会影响A
异步
A发送消息后,可以立即返回,B可以在自己的节奏下处理消息
削峰
在高并发情况下,消息队列可以作为一个缓冲区,将请求暂时存储在队列中,不会立即推送到下游服务
- 这样即使在高峰期,系统也不会因为瞬时大量请求而卡死或崩溃

6万+

被折叠的 条评论
为什么被折叠?



