消息中间件介绍(中间件,两种消息模型),分布式系统为什么需要

目录

消息中间件

介绍

中间件

消息中间件

点对点(P2P)模型

发布/订阅(Pub/Sub)模型

消息队列

为什么分布式系统需要

[HTTP / RPC 直连通信](#HTTP / RPC 直连通信)

介绍

缺点

数据库轮询

介绍

缺点

[共享内存 / 本地文件](#共享内存 / 本地文件)

介绍

缺点

消息中间件

解耦

异步

削峰


消息中间件

介绍

中间件

帮助 应用程序其他应用程序/网络/硬件/操作系统 交互或通信的软件

  • 也就是将 具体业务 和 底层逻辑 解耦的软件
  • 应用程序只需通过中间件提供的接口进行操作,不需要关心如何实现底层的网络协议、数据存储、事务管理等,具体的访问细节由中间件去补足
  • 中间件包含多种类型 -- 数据库中间件 / 消息中间件 / 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可以在自己的节奏下处理消息

削峰

在高并发情况下,消息队列可以作为一个缓冲区,将请求暂时存储在队列中,不会立即推送到下游服务

  • 这样即使在高峰期,系统也不会因为瞬时大量请求而卡死或崩溃
相关推荐
阿昌喜欢吃黄桃15 天前
RocketMq事务消息原理
java·中间件·消息队列·rocketmq·mq
半夜修仙16 天前
延迟队列的介绍及常见问题
java·数据库·中间件·rabbitmq
手握风云-16 天前
一条消息的旅程:RabbitMQ 学习与实践(一)
中间件·rabbitmq
RH23121117 天前
2026.6.8Linux
java·数据库·中间件
理人综艺好会17 天前
双Token机制在实际项目中的应用与实践
中间件·token
番茄去哪了18 天前
神领物流面试题(一)
java·大数据·中间件
念何架构之路18 天前
消息中间件
中间件
都说名字长不会被发现18 天前
Spring Boot Starter 中间件账号密码加密方案设计与实现
java·spring boot·后端·中间件
瀚高PG实验室19 天前
java中间件无法连接数据库
java·数据库·中间件·瀚高数据库
之歆19 天前
Day11_Express 深入解析:从中间件到项目实战
中间件·express