一、RocketMQ
1.1 MQ的应用场景
- 任务异步处理。将不需要同步处理的并且消耗长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。
- 应用程序解耦
- 日志收集
交互流程:
- 采集系统从log日志文件采集数据,发送至消息队列
- 各日志需求服务从消息队列接收消息进行日志处理
1.2 RocketMQ介绍
是阿里开源的一款非常优秀的中间件产品,现已成为apache基金会的顶级项目。
1.3消息队列技术选型对比
消息队列有哪些
activeMq、RabbitMQ,ZeroMQ、Kafka、MetaMQ、Redis
RabbitMQ优点:
- 支持AMQP协议
- 基于erlang语言开发,高并发性能较好
- 工作模式较为灵活
- 支持延迟消息
- 提供较为友好的后台管理页面
- 单级部署,1-2WTPS
RabbitMQ缺点:
- 不支持水平扩容
- 不支持事务
- 消息吞吐量三者最差
- 当产生消息堆积,性能下降明显
- 消息重发机制需要手动设置
- 不支持消息重复消费
RocketMQ优点:
- 高可用,高吞吐量,海量消息堆积,低延迟性能上,都表现出色
- api与架构设计更加贴切业务场景
- 支持顺序消息
- 支持事务消息
- 支持消息过滤
- 支持重复消费
- 支持延迟消息
- 支持消息跟踪
- 天然支持集群、负载均衡
- 支持指定次数和时间间隔的失败消息重发
- 单机部署,5-10WTPS
RocketMQ缺点:
- 生态圈相比较kafka有所不如
- 消息吞吐量与消息堆积能力也不如kafka
- 不支持主从自动切换
- 只支持java
Kafka优点:
- 高可用,高吞吐量,低延迟性能上,表现出色
- 使用人数多,技术生态圈完善
- 支持顺序消息
- 支持多种客户端
- 支持重复消费
Kafka缺点:
- 依赖分区,消费者数量受限于分区数
- 单级消息过多时,性能下降明显
- 不支持事务消息
- 不支持指定次数和时间间隔的失败消息重发
1.4Rocket三种消息发送方式
- 同步消息
producer向broker发送消息,执行API时同步等待,直到broker服务器返回发送结果。
2.异步消息
producer向broker发送消息时指定消息发送成功及发送异常的回调方法,调用API后立即返回,producer发送消息线程不阻塞,消息发送成功或失败的回调任务在一个新的线程中执行
3.单向消息
producer向broker发送消息,执行API时直接返回,不等待broker服务器的结果
1.5Rocket消息结构
RocketMQ的消息包括基础属性和扩展性两部分:
- 基础属性
- topic:主题相当于消息的一级分类,具有相同的topic的消息将发送至该topic下的消息队列中,比如说一个电商系统可以分为商品消息、订单消息、物流消息等,就可以在broker中创建商品主题、订单主题等,所有商品的消息发送至该主题下的消息队列中。
- 消息体:即消息的内容,可以是字符串、对象等类型(可系列化)。消息的最大长度是4M。
- 消息Flag:消息的一个标记,RockerMQ不处理,留给业务系统使用。
2.扩展属性
- tag:相当于消息的二级分类,用于消费消息时进行过滤,可为空。
- keys:message索引键,在运维中可以根据这些key快速检索到消息,可为空。
- waitStoreMsgOK:消息发送时是否等消息存储完成后再返回。
1.6消息中间件对比
|
Kafka |
RocketMQ |
RabbitMQ | |
|
定位 |
日志消息、监控数据 |
非日志的可靠消息传输 |
非日志的可靠消息传输 |
|
可用性 |
非常高、分布式、主从 |
非常高 分布式、主从 |
高 主从、采用镜像模式实现、数据量大时可能有性能问题 |
|
消息可靠性 |
异步刷盘,容易丢数据 |
同步刷盘、异步刷盘 |
同步刷盘 |
|
单级吞吐量 |
百万级 |
十万级 |
万级 |
|
堆积能力 |
非常好 |
非常好 |
一般 |
|
顺序消费 |
支持 一台broker宕机后,消息会乱序 |
支持 顺序消息场景下,消费失败时消费队列将会暂停 |
支持 如果一个消费失败,此消息的顺序会被打乱 |
|
定时消息 |
不支持 |
支持 |
支持 |
|
事务消息 |
不支持 |
支持 |
不支持 |
|
消息重试 |
不支持 |
支持 |
支持 |
|
死信队列 |
不支持 |
支持 |
支持 |
|
访问权限 |
无 |
无 |
类似数据库,配置用户名和密码 |
1.7RocketMQ启动命令
- 启动Name Server: mqnamesrv.cmd
- 启动Broker(cmd启动):mqbroker.cmd -n localhost:9876 autoCreateTopicEnable=true
- 发送消息:tools.cmd org.apache.rocketmq.example.quickstart.Producer
- 接收消息:tools.cmd org.apache.rocketmq.example.quickstart.Consumer
2.RibbitMQ
2.1 概念
- MQ称为Message Queue,消息队列,RibbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue高级消息队列协议)协议实现的消息队列,是一种应用程序之间的通信方法。
应用场景:
- 任务异步处理
将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。
2. 应用程序解耦合
MQ相当于一个中介,生产方通过MQ与消费方进行交互,它将应用程序进行解耦合。
其他的消息队列:
ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ、Redis
RibbitMQ的优点:
- 使用简单,功能强大。
- 基于AMQP协议。
- 社区活跃,文档完善。
- 高并发性能好,原因是在于开发语言erlang。
- Spring Boot默认已经继承了RabbitMQ。
2.2 AMQP与JMS协议
AMQP是一套公开的消息队列协议,它从协议层定义消息通信数据的标准格式,主要就是解决MQ市场上协议不统一的问题。RabbitMQ是遵循AMQP标准协议开发的MQ服务。
JMS是java提供的一套消息服务API标准,目的是为所有的java应用程序提供统一的消息通信的标准,只要遵循JMS标准的应用程序之间都可以进行消息通信。
两者的区别:
JMS是java语言专属的消息服务标准,它是在api层定义标准,并且只能用于java应用;而AMQP是在协议层定义的标准,是跨语言的。
2.3 RabbitMQ的工作原理

组成部分说明:
Broker:消息队列服务进程,该进程有两个部分Exchange和Queue
Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过滤。
Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的消费方。
Producer:消息生产者,将消息发送到MQ
Consumer:消息消费者,接收MQ转发的消息
2.4 消息发布接收流程
--发送消息--
- 生产者和Broker建立TCP连接
- 生产者和Broker建立通道
- 生产者通过通道消息发送给Broker,有Exchange将消息进行转发
- Exchange将消息转发到之指定的Queue
--接收消息--
- 消费者和Broker建立TCP连接
- 消费者和Broker建立通道
- 消费者监听指定的Queue
- 当有消息到达Queue时Broker默认将消息推送给消费者
- 消费者接收到消息
2.5 工作模式
- Work queues
- Publish/Subscribe
- Routing
- Topics
- Header
- RPC
Work queues简单模式:配置消息队列即可,有默认的交换器

2.Publish/Subscribe订阅发布模式:配置消息队列、交换器、消息队列和交换器的绑定;交换器对象:FanoutExchange
3.Routing路由模式:一对多,在订阅发布模式升级,在交换器绑定中加入routing key在生产者发送中加入路由key;交换器对象:DirectExchan
ge
4.Topic主题模式(常用):*.*,#;#可以匹配多个值,*只能匹配一个值;交换器对象:TopicExchange
5.Header模式:可以传参数
1.工作模式发布订阅模式:

1.每个消费者监听自己的队列
2.生产者将消息发给broker,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收到
消息路由模式: 1.每个消费者监听自己的队列,并设

置routingKey
2.生产者将消息发给交换机,由交换机根据rountingkey来转发消息到指定的队列
topics主题模式: 1.队列绑定交换机

指定通配符:
2.通配符规则:中间以"."分割,符号#可以匹配多个,*只能匹配一个
Header模式: header模式与routing不同的地方在于
,header模式取消rountingkey,使用header中的key/value(键值对)匹配
3
3.1RabbitMQ特点
- 可靠性:RabbitMQ使用一些机制来保证可靠性, 如持久化、传输确认及发布确认等。
- 灵活的路由:在消息进入队列之前,通过交换器来路由消息。对于典型的路由功能, RabbitMQ 己经提供了一些内置的交换器来实现。针对更复杂的路由功能,可以将多个 交换器绑定在一起, 也可以通过插件机制来实现自己的交换器
- 扩展性:多个RabbitMQ节点可以组成一个集群,也可以根据实际业务情况动态地扩展 集群中节点。
- 高可用性:队列可以在集群中的机器上设置镜像,使得在部分节点出现问题的情况下队 列仍然可用。
- 多种协议:RabbitMQ除了原生支持AMQP协议,还支持STOMP, MQTT等多种消息 中间件协议。
- 多语言客户端:RabbitMQ 几乎支持所有常用语言,比如 Java、 Python、 Ruby、 PHP、 C#、 JavaScript 等。
- 管理页面:RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息、集 群中的节点等。
3.2 AMQP是什么
- RabbitMQ就是 AMQP 协议的 Erlang 的实现(当然 RabbitMQ 还支持 STOMP2、 MQTT3 等协议 ) AMQP 的模型架构 和 RabbitMQ 的模型架构是一样的,生产者将消息发送给交换器,交换器和队列绑定 。
RabbitMQ 中的交换器、交换器类型、队列、绑定、路由键等都是遵循的 AMQP 协议中相 应的概念。目前 RabbitMQ 最新版本默认支持的是 AMQP 0-9-1。
3.3 AMQP协议3层
Module Layer:协议最高层,主要定义了一些客户端调用的命令,客户端可以用这些命令实现自己的业务逻辑。
Session Layer:中间层,主要负责客户端命令发送给服务器,再将服务端应答返回客户端,提供可靠性同步机制和错误处理。
TransportLayer:最底层,主要传输二进制数据流,提供帧的处理、信道服用、错误检测和数据表示等。
3.4 RabbitMQ是什么
RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而群集和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。
PS:也可能直接问什么是消息队列?消息队列就是一个使用队列来通信的组件
3.5 AMQP模型的几大组件
- 交换机(Exchange):消息代理服务器中用于把消息路由到队列的组件
- 队列(Queue):用来存储消息的数据结构,位于硬盘或内存中
- 绑定(Binding):一套规则,告知交换器消息应该将消息投递给那个队列
3.6 说说生产者Producer和消费者Consumer
--生产者--
- 消息生产者,就是投递消息的乙方
- 消息一般包含两个部分:消息体和标签(Label)
--消费者--
- 消费消息,也就是接收消息的一方
- 消费者连接到RabbitMQ服务器,并订阅到队列上。消费消息时只消费消息体,丢弃标签。
3.7 Broker服务节点、Queue队列、Exchange交换器
- Broker可以看做RabbitMQ的服务节点。一般请下一个Broker可以看做一个RabbitMQ服务器。
- Queue:RabbitMQ的内部对象,用于存储消息。多个消费者可以订阅同一队列,这时队列中的消息会被平摊(轮询)给多个消费者进行处理。
- Exchange:生产者将消息发送到交换器,由交换器将消息路由到一个或者多个队列中。当路由不到时,或返回给生产者或直接丢弃。
3.8 如何保证消息的可靠性
- RabbitMQ自身:持久化、集群、普通模式、镜像模式
- RabbitMQ到消费者:basicAck机制、死信队列、消息补偿机制
3.9 什么是RoutingKey路由键
生产者将消息发送给交换器的时候,会指定一个RoutingKey,用来指定这个消息的路由规则,这个RoutingKey需要与交换器类型和绑定键联合使用才能最终生效
3.10 什么是Binding绑定
通过绑定交换器和队列关联起来,一般会指定一个BindingKey,这样RabbitMQ就知道如何正确将路由消息到队列了。
3.11 交换器无法根据自身类型和路由键找到符合条件队列时,有哪些处理
- mandatory:true返回消息给生产者
- mandatory:false直接丢弃
3.12 什么是死信队列
DLX,全称Dead-Letter-Exchange,死信交换器,死信邮箱。当消息在一个队列中变成死信之后,她就能被重新发送到另一个交换器中,这个交换器就是DLX,绑定DXL的队列就称之为死信队列。
3.13 导致死信的几种原因
- 消息被拒且requeue=false
- 消息TTL过期
- 队列已满,无法再添加
3.14 延迟队列
存储对应的延迟消息,指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。
3.15 优先级队列
- 优先级高的队列会先被消费
- 可以通过x-max-priority参数来实现
- 当消费速度大于生产速度且Broker没有堆积的情况下,优先级显得没有意义。
3.16 事务机制
- channel.txSelect用于将当前的信道设置成事务模式
- channel.txCommit用于提交事务
- channel.txRollback用于事务回滚,如果在事务提交执行之前由于RabbitMQ异常崩溃或者其他原因抛出异常,通过txRollback来回滚
3.17 什么是发送确认机制
生产者把信道设置为confirm确认模式,设置后,所有再改信道发布的消息都会被指定一个唯一的ID,一旦消息被投递到所有匹配的队列之后,RabbitMQ就会发送一个确认(Basic.Ack)给生产者(包含消费的唯一ID),这样生产者就知道消息到达对应的目的地了。
3.18 消费者获取消息的方式
- 堆
- 拉
3.19 消费者由于某些原因无法处理当前接受的消息如何来拒绝
- channel.basicNack
- channel.basicReject
3.20 消息传输如何保证层级
- At most once:最多一次。消息可能会丢失,但不会重复传输
- At least once:最少一次。消息绝不会丢失,但可能会重复传输
- Exactly once:恰好一次,每条消息肯定仅传输一次
3.21 集群中的节点类型
- 内存节点:ram,将变更写入内存
- 磁盘节点:disc,磁盘写入操作
- RabbitMQ要求最少有一个磁盘节点
3.22 RabbitMQ中消息可能有的几种状态
- alpha: 消息内容(包括消息体、属性和 headers) 和消息索引都存储在内存中 。
- beta: 消息内容保存在磁盘中,消息索引保存在内存中。
- gamma: 消息内容保存在磁盘中,消息索引在磁盘和内存中都有 。
- delta: 消息内容和索引都在磁盘中 。
3.23 在哪种场景下使用消息中间件
- 接口之间耦合比较严重
- 面对大流量并发时,容易被冲垮
- 存在性能问题
3.24 如何保证RabbitMQ消息队列的高可用
RabbitMQ有三种模式:单级、普通集群、镜像集群模式
- 单机模式:就是demo级别的
- 普通集群模式:在多台机器上启动多个RabbitMQ实例,每个机器启动一个
- 镜像集群模式:高可用模式
本文详细介绍了RocketMQ和RabbitMQ两种消息队列,包括它们的应用场景、优缺点、消息发送方式、消息结构和工作原理。RocketMQ在高可用和性能方面表现出色,支持顺序消息和事务消息,而RabbitMQ以其简单易用和强大的社区支持著称,基于AMQP协议。两者各有特点,适用于不同的业务需求。

6671

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



