消息队列MQ核心原理全面总结(11大必会原理)
消息队列已经逐渐成为分布式应用场景、内部通信、以及秒杀等高并发业务场景的核心手段,它具有低耦合、可靠投递、广播、流量控制、最终一致性 等一系列功能。
无论是 RabbitMQ、RocketMQ、ActiveMQ、Kafka还是其它等,都有的一些基本原理、术语、机制等,总结分享出来,希望大家在使用消息队列技术的时候能够快速理解。
1. 消息生产者、消息者、队列
- 消息生产者Producer:发送消息到消息队列。
- 消息消费者Consumer:从消息队列接收消息。
- Broker:概念来自与Apache ActiveMQ,指MQ的服务端,帮你把消息从发送端传送到接收端。
- 消息队列Queue:一个先进先出的消息存储区域。消息按照顺序发送接收,一旦消息被消费处理,该消息将从队列中删除。
2.设计Broker主要考虑
1)消息的转储:在更合适的时间点投递,或者通过一系列手段辅助消息最终能送达消费机。
2)规范一种范式和通用的模式,以满足解耦、最终一致性、错峰等需求。
3)其实简单理解就是一个消息转发器,把一次RPC做成两次RPC。发送者把消息投递到broker,broker再将消息转发一手到接收端。
总结起来就是两次RPC加一次转储,如果要做消费确认,则是三次RPC。
3. 点对点消息队列模型
点对点模型 用于 消息生产者 和 消息消费者 之间 点到点 的通信。

点对点模式包含三个角色:
- 消息队列(Queue)
- 发送者(Sender)
- 接收者(Receiver)
每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,可以放在 内存 中也可以 持久化,直到他们被消费或超时。
特点
- 每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)
- 发送者和接收者之间在时间上没有依赖性
- 接收者在成功接收消息之后需向队列应答成功
4. 发布订阅消息模型Topic

发布订阅模型包含三个角色:
- 主题(Topic)
- 发布者(Publisher)
- 订阅者(Subscriber)
多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。
特点
- 每个消息可以有多个消费者:和点对点方式不同,发布消息可以被所有订阅者消费
- 发布者和订阅者之间有时间上的依赖性。
- 针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息。
- 为了消费消息,订阅者必须保持运行的状态。
5.点对点和发布订阅的区别
生产者发送一条消息到队列queue,只有一个消费者能收到。
发布者发送到topic的消息,只有订阅了topic的订阅者才会收到消息。
6. 消息的顺序性保证
基于Queue消息模型,利用FIFO先进先出的特性,可以保证消息的顺序性。
7. 消息的ACK机制
即消息的Ackownledge确认机制,
为了保证消息不丢失,消息队列提供了消息Acknowledge机制,即ACK机制,当Consumer确认消息已经被消费处理,发送一个ACK给消息队列,此时消息队列便可以删除这个消
息了。如果Consumer宕机/关闭,没有发送ACK,消息队列将认为这个消息没有被处理,会将这个消息重新发送给其他的Consumer重新消费处理。
8.最终一致性的设计思路
主要是用“记录”和“补偿”的方式。
本地事务维护业务变化和通知消息,一起落地,然后RPC到达broker,在broker成功落地后,RPC返回成功,本地消息可以删除。否则本地消息一直靠定时任务轮询不断重发,这样就保证了消息可靠落地broker。
broker往consumer发送消息的过程类似,一直发送消息,直到consumer发送消费成功确认。
我们先不理会重复消息的问题,通过两次消息落地加补偿,下游是一定可以收到消息的。然后依赖状态机版本号等方式做判重,更新自己的业务,就实现了最终一致性。
如果出现消费方处理过慢消费不过来,要允许消费方主动ack error,并可以与broker约定下次投递的时间。
对于broker投递到consumer的消息,由于不确定丢失是在业务处理过程中还是消息发送丢失的情况下,有必要记录下投递的IP地址。决定重发之前询问这个IP,消息处理成功了吗?如果询问无果,再重发。
事务:本地事务,本地落地,补偿发送。本地事务做的,是业务落地和消息落地的事务,而不是业务落地和RPC成功的事务。消息只要成功落地,很大程度上就没有丢失的风险。
9. 消息的事务支持
消息的收发处理支持事务,例如:在任务中心场景中,一次处理可能涉及多个消息的接收、处理,这应该处于同一个事务范围内,如果一个消息处理失败,事务回滚,消息重新回到队列中。
10. 消息的持久化
消息的持久化,对于一些关键的核心业务来说是非常重要的,启用消息持久化后,消息队列宕机重启后,消息可以从持久化存储恢复,消息不丢失,可以继续消费处理。
11. 消息队列的高可用性
在实际生产环境中,使用单个实例的消息队列服务,如果遇到宕机、重启等系统问题,消息队列就无法提供服务了,因此很多场景下,我们希望消息队列有高可用性支持,例如
RabbitMQ的镜像集群模式的高可用性方案,ActiveMQ也有基于LevelDB+ZooKeeper的高可用性方案,以及Kafka的Replication机制等。
12.消息队列的选型和应用场景
具体请参考:高并发架构系列:分布式之消息队列的特点、选型、及应用场景详解
以上
作者简介
陈睿|mikechen,10年+大厂架构经验,《BAT架构技术500期》系列文章作者,分享十余年架构经验以及面试心得!
阅读mikechen的互联网架构更多技术文章合集
Java并发|JVM|MySQL|Spring|Redis|分布式|高并发|架构师
消息队列MQ核心原理全面总结(11大必会原理)的更多相关文章
- 高性能消息队列 CKafka 核心原理介绍(上)
欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:闫燕飞 1.背景 Ckafka是基础架构部开发的高性能.高可用消息中间件,其主要用于消息传输.网站活动追踪.运营监控.日志聚合.流式 ...
- 消息队列 MQ 入门理解
功能特性: 应用场景: 消息队列 MQ 可应用于如下几个场景: 分布式事务 在传统的事务处理中,多个系统之间的交互耦合到一个事务中,响应时间长,影响系统可用性.引入分布式事务消息,交易系统和消息队列之 ...
- java面试记录三:hashmap、hashtable、concurrentHashmap、ArrayList、linkedList、linkedHashmap、Object类的12个成员方法、消息队列MQ的种类
口述题 1.HashMap的原理?(数组+单向链表.put.get.size方法) 非线程安全:(1)hash冲突:多线程某一时刻同时操作hashmap并执行put操作时,可能会产两个key的hash ...
- 详解RPC远程调用和消息队列MQ的区别
PC(Remote Procedure Call)远程过程调用,主要解决远程通信间的问题,不需要了解底层网络的通信机制. RPC框架 知名度较高的有Thrift(FB的).dubbo(阿里的). RP ...
- 为什么会需要消息队列(MQ)?
为什么会需要消息队列(MQ)? #################################################################################### ...
- 消息队列一:为什么需要消息队列(MQ)?
为什么会需要消息队列(MQ)? #################################################################################### ...
- 消息队列MQ简介
项目中要用到RabbitMQ,领导让我先了解一下.在之前的公司中,用到过消息队列MQ,阿里的那款RocketMQ,当时公司也做了简单的技术分享,自己也看了一些博客.自己在有道云笔记上,做了一些整理,但 ...
- 消息队列MQ集合
消息队列MQ集合 消息队列简介 kafka简介 Centos7部署zookeeper和Kafka集群 .
- 高并发系统:消息队列MQ
注:前提是知道什么是消息队列.不懂的去搜索各种消息队列入门(activeMQ.rabbitMQ.rocketMQ.kafka) 1.为什么要使用MQ?(MQ的好处:解耦.异步.削峰) (1)解耦:主要 ...
随机推荐
- NC16561 [NOIP2012]国王的游戏
NC16561 [NOIP2012]国王的游戏 题目 题目描述 恰逢 H 国国庆,国王邀请 \(n\) 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上 ...
- P3480 [POI2009]KAM-Pebbles 题解
题目链接 首先,这道题看上去就是个博弈论,很显然的 \(Nim\) 游戏. 因为每一个的取法都和它的上一位有关. 有一种非常显然的转换方式 :我们把这若干堆石子从前向后做一个差分 . 我们记 \(a_ ...
- 扩展-PageHelper分页插件
1.PageHelper 分页插件简介 1) PageHelper是MyBatis中非常方便的第三方分页插件 2) 官方文档: https://github.com/pagehelper/Mybati ...
- Dapr v1.8 正式发布
Dapr是一套开源.可移植的事件驱动型运行时,允许开发人员轻松立足云端与边缘位置运行弹性.微服务.无状态以及有状态等应用程序类型.Dapr能够确保开发人员专注于编写业务逻辑,而不必分神于解决分布式系统 ...
- java枚举和注解
枚举 一.枚举(enumeration) 是一组常量的集合,可以理解为:枚举属于一种特殊的类,里面只包含一组有限的特定的对象,构造方法默认为private. 二.枚举的两种实现方式 1.自定义实现枚举 ...
- 使用Docker搭建自己的Bitwarden密码管理服务
相信身为开发者,总会在各种网站中注册账号,为了方面记忆可以使用同一套账号密码进行注册,自从前段时间学习通时间撞库后有些人已经开始疯狂改密码了,可是密码一多就很难记忆,最好找个地方存储账户信息 我曾经使 ...
- 关于标准IO缓冲区的问题
关于标准IO缓冲区的问题 按照标准IO缓冲区可以分为三类: 不缓存类型: 一旦有数据,直接将数据写入到文件 行缓冲类型: 同全缓冲类型 遇到\n时,将数据写入文件 全缓冲类型: 当程序结束,将数据冲洗 ...
- qbxt五一数学Day2
目录 1. 判断素数(素性测试) 1. \(O(\sqrt n)\) 试除 2. Miller-Rabin 素性测试 * 欧拉函数 2. 逆元 3. exgcd(扩展欧几里得) 4. 离散对数(BSG ...
- iOS自动化打包 Jenkins+Gitlab+Fastlane+蒲公英+钉钉
前言 这两天花时间整理一下自动化打包的整套流程,现在iOS端的整套流程是没有问题了,这个过程中踩得坑也的确是特别多,所以这周末把整个流程整理一下,总结出来这篇文章,希望能对有需要的小伙伴有点点帮助. ...
- WPF 截图控件之文字(七)「仿微信」
前言 接着上周写的截图控件继续更新添加 文字. 1.WPF实现截屏「仿微信」 2.WPF 实现截屏控件之移动(二)「仿微信」 3.WPF 截图控件之伸缩(三) 「仿微信」 4.WPF 截图控件之绘制方 ...