02_RabbitMQ集群原理及常见生产问题
2020-02-20 22:01:40 43 举报
RabbitMQ集群原理及常见生产问题
作者其他创作
大纲/内容
消息顺序不对场景
消费者
数据2
优点:只是能从多个MQ中去消费数据,能提高吞吐量而已。缺点1:可能在rabbitMQ集群内产生大量的消息传输。缺点2:可用性几乎没有什么保障,如果queue所在的节点宕机了,就导致那个queue的数据丢失了,消费者无法消费。故不是高可用的。
3、消费者消费消息
生产者
数据3
数据库
RabbitMQ
问题3:消费者消费到了这个消费,但是来没有来得及处理,消费者挂掉了,但是MQ以为消费者处理完了这个消息。因为打开了消费者打开了消息autoAck通知机制。你消费到了数据之后,会自动通知MQ说,ok已经消费完了这一条消息。如果你消费到了这条消息,正在处理这个消息,此时消费者就自动autoAck了,通知MQ这条消息已经消费了。刚好不巧,此时消费者宕机了,那这条消息就丢失了。而且MQ还以为你处理完了。
queue(元数据和实际数据)一条数据一条数据一条数据。。。
2、C从B中拉取数据
说明:一个数据只能会被一个数据消费掉
queue元数据
RabbitM节点C
数据1
磁盘
2、将数据同步节点A
通知生产者消息1 已经接收到
RabbitM节点B
消息1
RabbitMQ(实例B)部署在独立的一台机器上
手动通知消息1 已经处理完
queue1
问题1 解决方案1:事务机制channel.txSelect();try{ // 发送消息}catch( Exception e){ channel.txRollback(); // 再次重发消息}channel.txCommit();事务同步机制是同步的,生产者发送消息会同步阻塞卡住,等待你是成功还是失败。导致生产者发送消息的吞吐量降下来
queue3
queue
1、生产者将数据发送到MQ
说明:假设rabbitMQ有3台机器,每台机器都启动了一个进程,作为集群中的一个节点。
说明:需要保证消息顺序性的消息发到一个queue中
持久化
RabbitMQ(实例C)部署在独立的一台机器上
普通集群模式原理分析
问题1 解决方案2(推荐使用):confirm机制1、先把channel设置成confirm2、发送一个消息3、发送完消息之后就不用管了4、rabbitMQ如果接收到了这个消息的话,就会回调你生产者本地的一个接口。通知你说这条消息我已经收到了。5、rabbitMQ在接收消息时报错了,会回调,你生产者本地的一个接口,告诉你这个消息接收失败了,你可以再次重发。生产者这块如果要保证消息不丢,一般是用的confirm机制,异步模式,发送消息之后不会阻塞,直接可以发送下一个消息,这个吞吐量会高些。代码:channel.confirm();// 发送一个消息在生产者提供一个供回调的回调接口public void ack(String MessageId){}public void nack(String MessageId){// 重发一次消息}
保证消息的顺序性
说明:每个节点上都有节点B中queue的完整镜像,就是包含了这个queue的全部数据所以叫镜像集群模式
数据丢失问题
问题1 解决方案1: 第一个是创建queue的时候将其设置为持久化的,这样就可以保证rabbitmq持久化queue的元数据,但是不会持久化queue里的数据; 第二个是发送消息的时候将消息的deliveryMode设置为2,就是将消息设置为持久化的,此时rabbitmq就会将消息持久化到磁盘上去。 必须要同时设置这两个持久化才行,rabbitmq哪怕是挂了,再次重启,也会从磁盘上重启恢复queue,恢复这个queue里的数据。
3、将数据给消费者
queue2
镜像集群模式分析
RabbitM节点A
任何一个节点宕机,没问题,其它节点还包含了queue的完整数据,别的comsumer都可以到其它节点上去消费数据。故是高可用的。缺点:不是分布式的。假如queue里数据量很大,超过了queue的最大容量,该怎么办?
问题1 解决方案1:消费者层面,将autoAck关闭,然后每处理完一条消息之后,自己发送ack消息已经处理完。
问题1:发送消息的过程中,消息还没有到MQ在网络传输过程中就丢失了。或者消息到了MQ但是发生内部错误了,还没有存下来。
RabbitMQ(实例A)部署在独立的一台机器上
问题2:MQ接收到消息后暂存在自己内存里,消费者还没来得及消费,MQ自己挂掉了,导致暂存在内存中的消息丢失了。
0 条评论
下一页