RabbitMQ
2023-03-11 22:06:13 1 举报
AI智能生成
RabbitMQ梳理
作者其他创作
大纲/内容
消息丢失
出现原因
消息发出后,中途网络故障,服务器没收到
消息发出后,服务器收到了,还没持久化,服务器宕机
消息发出后,服务器收到了,消费方还未处理业务逻辑,服务却挂掉了,而消息也自动签收,等于啥也没干
解决方案
生产方发送消息时,要try...catch,在catch中捕获异常,并将MQ发送的关键内容记录到日志表中,日志表中要有消息发送状态,若发送失败,由定时任务定期扫描重发并更新状态
生产方publisher必须要加入确认回调机制,确认成功发送并签收的消息,如果进入失败回调方法,就修改数据库消息的状态,等待定时任务重发
消费方要开启手动签收ACK机制,消费成功才将消息移除,失败或因异常情况而尚未处理,就重新入队
消息重复
出现原因
消息消费成功,事务已提交,签收时结果服务器宕机或网络原因导致签收失败,消息状态会由unack转变为ready,重新发送给其他消费方
消息消费失败,由于retry重试机制,重新入队又将消息发送出去
解决方案
消费方业务接口做好幂等
消息日志表保存MQ发送时的唯一消息ID,消费方可以根据这个唯一ID进行判断避免消息重复
消费方的Message对象有个getRedelivered()方法返回Boolean,为TRUE就表示重复发送过来的
消息积压
出现原因
消费方的服务挂掉,导致一直无法消费消息
消费方的服务节点太少,导致消费能力不足,从而出现积压,这种情况极可能就是生产方的流量过大导致
解决方案
既然消费能力不足,那就扩展更多消费节点,提升消费能力
建立专门的队列消费服务,将消息批量取出并持久化,之后再慢慢消费
消息保证顺序
将原来的一个queue拆分成多个queue,每个queue都有一个自己的consumer
还是一个queue,但是也只对应一个consumer,然后这个consumer内部用内存队列做排队,然后分发给底层不同的worker来处理 。
RabbitMQ的高级应用
延时队列
rabbitmq_delayed_message_exchange插件,实现延迟队列效果
使用场景
订单在30分钟之内未支持,则自动取消订单
工单在60分钟之内仍未处理,则发送消息提醒
预定会议室后,在预定时间前10分钟,通知提醒各参会人员
死信队列
变成死信的几种情况
消息被拒绝(
channel.basicReject/channel.basicNack)并且request=false
channel.basicReject/channel.basicNack)并且request=false
消息在队列的存活时间超过设置的生存时间(TTL)时间
队列达到最大长度(队列满了,无法再添加数据到队列中)
死信队列的设置
首先,需要设置死信队列的Exchange和queue,然后进行绑定
需要在队列机上一个参数即可:arguments.put(“x-dead-letter-exchange”,”dlx.exchange”)
队列幂等性
使用全局ID
唯一标识(比如流水号/时间戳/UUID/订单号)
利用redis执行setnx命令,天然具有幂等性,从而实现不重复消费(推荐使用redis)
优先级队列
x-max-priority 参数设置
惰性队列
惰性队列会尽可能地将消息存入磁盘中,而在消费者消费消息时才会被加载到内存中,它支持更多的消息存储
集群
主备模式
主备模式是读写都在主节点上面,备用节点是不进行任何的读写操,只用来实现当主节点宕机的情况下能顶上去
远程模式
远程模式能够实现双活的一种模式,又被叫做Shovel模式,它可以将消息进行不同数据中心的复制工作,能够跨地域的让两个MQ集群互联。
镜像模式
集群模式非常经典的就是Mirror镜像模式,保证100%数据不丢失,主要的目的是在于保证数据的高可靠性
多活模式
这种模式也是实现异地数据复制的主流模式,因为Shovel模式配置比较复杂,所以一般来说实现异地集群都是使用这种双活或者多活模式来去实现的
mq应用场景
流量削峰:解决高并发问题
应用解耦:提升系统可用性
异步处理:提升响应速度
消息队列的优缺点
系统可用性降低
系统复杂程度提高
一致性的问题
核心组成
producer
生产者,投递消息的程序
consumer
消费者,接受消息的程序
Broker
消息队列服务器实体
Connection(连接)
Channel(信道)
信道,打开信道才能进行通信,一个channel代码一个会话任务,它是真实 TCP 连接之上的虚拟连接
Exchange(交换机)
4种类型
direct(直连)
根据RouteKey完全匹配到接收队列中
可以使用default Exchange,不需要执行binding操作
fanout
将Exchange中所有的消息都发送到 与Exchange绑定的Queue中
topic
可以使用模糊匹配到queue中,匹配中的都发送
* 匹配一个单词
# 匹配0个或多个字符
需要执行Exchange和Queue的binding操作
headers
通过匹配AMQP消息的header而非路由键
Queue(队列)
消息的载体,每个消息都会被投到一个或多个队列
Binding
绑定,把exchange和queue按照路由规则绑定起来
Routing Key
Routing Key
Virtual host(虚拟主机)
RabbitMQ工作流程详解
RabbitMQ的五种消息类型介绍
简单模式
一个生产者、一个消费者,不需要设置交换机(使用 默认的交换机)
工作队列模式 Work Queue
一个生产者、多个消费者(竞争关系),不需要设置交换机(使用默认 的交换机)
发布订阅模式 Publish/subscribe
需要设置类型为fanout的交换机,并且交换机和队列进行绑定, 当发送消息到交换机后,交换机会将消息发送到绑定的队列
路由模式 Routing
需要设置类型为direct的交换机,交换机和队列进行绑定,并且指定routing key,当发送消息到交换机后,交换机会根据routing key将消息发送到对应的队列
通配符模式 Topic
需要设置类型为topic的交换机,交换机和队列进行绑定,并且指定通配符方式的 routing key,当发送消息到交换机后,交换机会根据routing key将消息发送到对应的队列
持久化机制
队列queue持久化
durable设置为true
消息持久化
BasicProperties中设置deliveryMode设置为2
交换器exchange持久化
durable设置为true
RabbitMQ/kafka/rocketmq
单机吞吐量
RabbitMQ
万级,比 RocketMQ、Kafka 低一个数量级
RocketMQ
10 万级,支撑高吞吐
Kafka
10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响
RocketMQ
topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic
Kafka
topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源
时效性
RabbitMQ
微秒级,这是 RabbitMQ 的一大特点,延迟最低
RocketMQ
ms 级
Kafka
延迟在 ms 级以内
可用性
RabbitMQ
高,基于主从架构实现高可用
RocketMQ
非常高,分布式架构
Kafka
非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性
RabbitMQ
基本不丢
RocketMQ
经过参数优化配置,可以做到 0 丢失
Kafka
经过参数优化配置,可以做到 0 丢失
功能支持
RabbitMQ
基于 erlang 开发,并发能力很强,性能极好,延时很低
RocketMQ
MQ 功能较为完善,还是分布式的,扩展性好
Kafka
功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用
优缺点
RabbitMQ
优点
持久化:RabbitMQ可以保证所在的服务器宕机后,消息不会丢失。
高可用:部分机器宕机了还可以继续使用。
高级功能:如消息重试、死信队列等
缺点
首先是RabbitMQ吞吐量比较低,大概在每秒几万的样子,这样像对于大型电商促销秒杀就不能胜任。
集群线性扩展比较麻烦。
开发语言是erlang,懂得人不是很多,无法对其改造。
RocketMQ
优点
高吞吐量:大概普通机器有十万QPS往上。
消息可靠性
生产者的可靠性保证:生产者发送消息后返回SendResult,如果isSuccess返回true,则表示消息已经确认发送到服务器并被服务器接收保存。整个发送过程是一个同步过程。
服务器的可靠性:消息生产者发送的消息,RocketMQ服务收到后在做必要的校验和检查之后马上保存到磁盘,写入成功后返回给生产者。因此可以确认每条发送结果为成功的消息都会被消息服务器写入磁盘。
消费者的可靠性:消费者是一条一条顺序消费的,之后在成功消费一条后才会消费吓一跳。如果在消费某一条消息时失败则会重试消费这条消息,默认为5次,如果超过最大次数仍然无法消费,则将消息保存到本地,后台线程继续重试消费,主线程则会继续往后走,消费队列后面的消息。
消息持久性:RocketMQ收到消息后,会将消息持久化到文件,并利用Linux文件系统内存来提高性能
消息实时性:RocketMQ采取长轮询+PULL模式保证消息的实时性
消息堆积:支持10亿级别的消息堆积,不会因为消息堆积影响性能
高级功能:如延迟消息、消息回朔等
使用的java开发
缺点
消息重复:对于消费者来说,通过拉取方式将消息保存到本地,消费完再向服务器返回,在网络异常的情况下可能会出现重复。
消息过滤
服务器端过滤:减少不必要消息传输,但是会增加服务器负担
客户端过滤:根据客户端需求来定制消息,缺点是客户端会收到对它来说没用的消息,如果客户端无法承载这么多消息就会导致故障
Kafka
优点
高吞吐量:即使在非常廉价的机器上,Kafka也能做到每秒处理几十万条消息,而它的延迟最低只有几毫秒
低延迟:延迟可以控制在ms以内
持久性:Kafka可以将消息直接持久化在普通磁盘上,且磁盘读写性能优异
扩展性:Kafka集群支持热扩展,Kaka集群启动运行后,用户可以直接向集群中添加
容错性:Kafka会将数据备份到多台服务器节点中,即使当某个服务器节点失效时,Zookeeper将通知生产者和消费者从而使用其他的节点,也不会影响整个系统的功能
支持多种客户端语言:Kafka支持Java、.NET、PHP、Python等多种语言
缺点
重复消息:Kafka保证每条消息至少送达一次,虽然几率很小,但一条消息可能被送达多次。
消息乱序:Kafka某一个固定的Partition内部的消息是保证有序的,如果一个Topic有多个Partition,partition之间的消息送达不保证有序
复杂性:Kafka需要Zookeeper的支持,Topic一般需要人工创建,部署和维护比一般MQ成本更高。
topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源。
0 条评论
下一页