目录
[1. 什么是MQ](#1. 什么是MQ)
[2. 为什么要用MQ【业务场景】](#2. 为什么要用MQ【业务场景】)
[2.1. 异步](#2.1. 异步)
[2.2. 应用解耦](#2.2. 应用解耦)
[2.3. 流量削峰](#2.3. 流量削峰)
[3. MQ的分类](#3. MQ的分类)
[4. MQ 的选择](#4. MQ 的选择)
[1. 简介](#1. 简介)
[2. 作用](#2. 作用)
[3. AMQP协议](#3. AMQP协议)
[4. 工作原理](#4. 工作原理)
[5. 工作模式](#5. 工作模式)
[(7)Publisher Confirms模式](#(7)Publisher Confirms模式)
一、MQ
1. 什么是MQ
MQ(message queue),从字面意思上看,本质是个队列,FIFO 先入先出,只不过队 列中存放的内容是
message 而已,还是一种跨进程的通信机制,用于上下游传递消息。 在互联网架构中,MQ 是一种非常常见的上
下游"逻辑解耦+物理解耦"的消息通信服 务。使用了 MQ 之后,消息发送上游只需要依赖 MQ,不用依赖其他
服务。
2. 为什么要用MQ【业务场景】
2.1. 异步
如: 用户注册发送,注册邮件、注册短信
传统做法 :
(1)、串行 (先发送邮件、再发短信)。问题:持续时间长
(2)、并行(将注册信息写入数据库后,同时发送邮件、短信),速度快、但不能满足高 吞吐需求
消息队列做法 :
将数据写入数据库、同时发送消息给发送邮件和注册,异步处理
2.2. 应用解耦
如:双十一购物节,用户下单后、订单系统通知库存系统。
传统做法 :
订单系统调用库存系统接口。问题:库存接口故障,订单就会失败,而损失大量订单
消息队列做法
订单系统:下单,订单系统完成持久化,将消息写入队列,返回下单成功给用户 库存系统:订阅下单的消息,获
取下单消息,进行库操作,就算库存系统故障,消息队 列也能保证消息可靠投递,不会导致消息丢失。
2.3. 流量削峰
如:秒杀活动、一般会因为流量过大,导致应用挂掉,一般在应用前端加入消息队列。 作用: 1、可以控制活动
人数,超过一定阈值,订单直接丢弃 2、可以缓解短时间的高流量压垮应用(应用程序按自己的最大处理能力获取
订单)
3. MQ的分类
(1)ActiveMQ
优点:单机吞吐量万级,时效性 ms 级,可用性高,基于主从架构实现高可用性, 消息可靠性较高,概率丢失数
据低
缺点: 官方社区现在对 ActiveMQ 5.x 维护越来越少,高吞吐量场景较少使用。
(2)Kafka
大数据的杀手锏,谈到大数据领域内的消息传输,则绕不开 Kafka,这款为大数据 而生的消息中间件, 以其百万
级 TPS 的吞吐量名声大噪,迅速成为大数据领域的宠 儿,在数据采集、传输、存储的过程中发挥着举足轻重的作
用。目前已经被 LinkedIn, Uber, Twitter, Netflix 等大公司所采纳。
优点: 性能卓越,单机写入 TPS 约在百万条/秒,最大的优点,就是吞吐量高。时 效性 ms 级可用性非常高,
kafka 是分布式的,一个数据多个副本,少数机器宕机,不 会丢失数据,不会导致不可用,消费者采用 Pull 方式获
取消息, 消息有序, 通过控制能够 保证所有消息被消费且仅被消费一次; 有优秀的第三方Kafka Web 管理界面
KafkaManager;在日志领域比较成熟,被多家公司和多个开源项目使用;功能支持: 功能较 为简单,主要支持
简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使 用
缺点:Kafka 单机超过 64 个队列/分区,Load 会发生明显的飙高现象,队列越多, load 越高,发送消息响应时
间变长,使用短轮询方式,实时性取决于轮询间隔时间,消 费失败不支持重试;支持消息顺序, 但是一台代理宕
机后,就会产生消息乱序,社区更 新较慢;
(3)RocketMQ
RocketMQ 出自阿里巴巴的开源产品,用 Java 语言实现,在设计时参考了 Kafka, 并做出了自己的一些改进。
被阿里巴巴广泛应用在订单,交易,充值,流计算,消息推 送,日志流式处理,binglog 分发等场景。
优点: 单机吞吐量十万级, 可用性非常高,分布式架构, 消息可以做到 0 丢失, MQ 功能较为完善,还是分布式的,
扩展性好, 支持 10 亿级别的消息堆积,不会因为堆积导 致性能下降, 源码是 java 我们可以自己阅读源码,定制自
己公司的 MQ
缺点:支持的客户端语言不多,目前是 java 及 c++,其中 c++不成熟;社区活跃度 一般,没有在MQ核心中去实
现 JMS 等接口,有些系统要迁移需要修改大量代码
(4)RabbitMQ
2007 年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息 系统,是当前最主流的消息
中间件之一。
优点: 由于 erlang 语言的高并发特性,性能较好;吞吐量到万级,MQ 功能比较完 备,健壮、稳定、易用、跨平
台、支持多种语言 如:Python、Ruby、.NET、Java、 JMS、C、PHP、ActionScript、XMPP、STOMP 等,支
持 AJAX 文档齐全;开源提供 的管理界面非常棒,用起来很好用,社区活跃度高;
更新频率相当高 https://www.rabbitmq.com/news.html
缺点:商业版需要收费,学习成本较高
4. MQ 的选择
(1)Kafka
主要特点是基于Pull 的模式来处理消息消费,追求高吞吐量,一开始的目的 就是用于日志收集和传输,适合产生
大量数据的互联网服务的数据收集业务。大型公司 建议可以选用,如果有日志采集功能, 肯定是首选 kafka 了。
(2)RocketMQ
天生为金融互联网领域而生,对于可靠性要求很高的场景,尤其是电商里面的订单扣 款,以及业务削峰,在大量
交易涌入时,后端可能无法及时处理的情况。RoketMQ 在 稳定性上可能更值得信赖,这些业务场景在阿里双 11
已经经历了多次考验,如果你的 业务有上述并发场景,建议可以选择 RocketMQ。
(3)RabbitMQ
结合 erlang 语言本身的并发优势,性能好时效性微秒级,社区活跃度也比较高,管 理界面用起来十分方便,如果
你的数据量没有那么大,中小型公司优先选择功能比较完 备RabbitMQ。
二、RabbitMQ
1. 简介
RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。
最初起源于金融系统,适用于对数据的一致性、稳定性和可靠性要求比较高的场景。
2. 作用
缓解高并发场景的压力;对流量进行削峰;实现解耦;提高系统的可靠性
3. AMQP协议
AMQP高级消息队列协议(Advanced Message Queueing Protocol),是面向消息的中间件的开放标准应用层
协议,AMQP的特征是消息导向,排队,路由(包括点对点和发布和订阅),可靠性和安全性。
AMQP要求消息传递提供商和客户端的行为在不同供应商实现可互操作的情况下,以与SMTP,HTTP,FTP等相
同的方式创建了可互操作的系统。
AMQP协议是具有现代特征的二进制协议。一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协
议的一个开发标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中
间件不同产品,不同开发语言等条件的限制。
AMQP是一种二进制应用层协议,旨在有效地支持各种消息应用和通信模式。
AMQP核心概念
AMQP协议模型
Server
又称作Broker,用于接受客户端的连接,实现AMQP实体服务;
Connection
连接,应用程序与Broker的网络连接;
Channel
网络信道,几乎所有的操作都在Channel中进行,Channel是进行消息读写的通道。客户端可建立多个Channel,每个Channel代表
一个会话任务;
Message
消息,服务器和应用程序之间传送的数据,有Properties和Body组成。Properties可以对消息进行修饰,比如消息的优先级、延迟等高级特性;Body则是消息体内容,即我们要传输的数据;
仅仅创建了客户端到Broker之间的连接后,客户端还是不能发送消息的。需要为每一个Connection创建Channel,AMQP协议规定
只有通过Channel才能执行AMQP的命令。一个Connection可以包含多个Channel。之所以需要Channel,是因为TCP连接的建立
和释放都是十分昂贵的,如果一个客户端每一个线程都需要与Broker交互,如果每一个线程都建立一个TCP连接,暂且不考虑TCP
连接是否浪费,就算操作系统也无法承受每秒建立如此多的TCP连接。RabbitMQ建议客户端线程之间不要共用Channel,至少要保
证共用Channel的线程发送消息必须是串行的,但是建议尽量共用Connection。
Virtual Host
虚拟地址,是一个逻辑概念,用于进行逻辑隔离,是最上层的消息路由。一个Virtual Host里面可以有若干个Exchange和Queue,
同一个Virtual Host里面不能有相同名称的Exchange或者Queue;
Virtual Host是权限控制的最小粒度;
Exchange
交换机,用于接收消息,可根据路由键将消息转发到绑定的队列;
Binding:
Exchange和Queue之间的虚拟连接,Exchange在与多个Message Queue发生Binding后会生成一张路由表,路由表中存储着
Message Queue所需消息的限制条件即Binding Key。当Exchange收到Message时会解析其Header得到Routing Key,
Exchange根据Routing Key与Exchange Type将Message路由到Message Queue。Binding Key由Consumer在Binding
Exchange与Message Queue时指定,而Routing Key由Producer发送Message时指定,两者的匹配方式由Exchange Type决定
Routing Key:
一个路由规则,虚拟机可用它来确定如何路由一个特定的消息;
Queue:
也称作Message Queue,即消息队列,用于保存消息并将他们转发给消费者;
RabbitMQ整体架构图
4. 工作原理
Broker:接收和分发消息的应用,RabbitMQ Server 就是 Message Broker
Virtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚 拟的分组中,类似于网络中的
namespace 概念。当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出多个 vhost,每
个用户在自己的 vhost 创建 exchange/queue 等
Connection:publisher/consumer 和 broker 之间的 TCP 连接
Channel:如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候 建立 TCP Connection 的开
销将是巨大的,效率也较低。Channel 是在 connection 内部建立的逻辑连接,如果应用程序支持多线程,通常
每个 thread 创 建单独的 channel 进行通讯,AMQP method 包含了 channel id 帮助客户端和 message
broker 识别 channel,所以 channel 之间是完全隔离的。Channel 作为轻 量级的Connection 极大减少了操作
系统建立 TCP connection 的开销
Exchange:message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到
queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast)
Queue:消息最终被送到这里等待 consumer 取走
Binding:exchange 和queue 之间的虚拟连接,binding 中可以包含 routing key, Binding 信息被保存到
exchange 中的查询表中,用于 message 的分发依据
简单来说:
1、生产者发送消息到MQ交换机
2、交换机根据定义的绑定规则和传过来的key将消息放到不同队列中
3、消费者从队列中取出消息进行消费
5. 工作模式
让我们看看官网:https://www.rabbitmq.com/tutorials/tutorial-one-java#hello-world
经过官网文档介绍,我们知道RabbitMQ的工作模式有七种
Hello Wold 简单模式/普通模式
Work queues 工作队列模式
Publish/Subscribe 发布订阅模式
Routing 路由模式
Topics 主题模式
RPC 远程调用模式
Publisher Confirms 发布确认模式
(1)普通模式
(2)Worker模式
类似于RocketMQ集群模式,发送消息只有一个消费者去消费。prefetchCount默认预取250个
消息,可以在配置文件中配置预取消息数量,实现各个节点多劳多得。消费速度快的就可以消费更多的消息。
spring.rabbitmq.listener.simple.prefetch=自定义预取数量
(3)PubSub模式
类似于RocketMQ广播模式,所有消费者都会收到消息。
生产者需要指定交换机,不需要指定队列。type ="fanout"
(4)Rounting模式
根据指定的交换机及路由key来发送消息,
即消费者绑定了与生产者发布的消息相同的路由key时才可以收到消息。
(5)Topic模式
Rounting模式的一种,交换机根据key的规则模糊匹配到对应的队列,由队列的监听消费者接收消息消费
(6)RPC模式
远程过程调用 或RPC