ToB企服应用市场:ToB评测及商务社交产业平台
标题:
RabbitMQ的高可用
[打印本页]
作者:
张裕
时间:
2024-8-28 00:42
标题:
RabbitMQ的高可用
1.Rabbit集群
接纳集群模式保护消息的完整。
1.1普通集群
在普通集群模式下,
各个节点之间有雷同的元数据,即队列布局,而消息不会冗余(不同节点的消息不同
)。
消费时,如果消费的不是存有数据的节点,RabbitMQ会临时在节点之间进行数据传输,将消息从存有数据的节点传输到消费的节点。(
客户端拉取消息时临时同步
)
缺点:
1
.普通集群的可靠性低,如果有个节点服务宕机了,那这个节点上的数据就无法消费了,需要等到这个节点服务规复后才气消费
。此时,消费者端已经消费过的消息就有大概给不了服务端正确应答,等服务重启后,大概会造成部分消息重复消费。别的,如果消息没有做恒久化,重启服务消息就会丢失。
2.普通集群模式也不支持高可用,即当某一个节点服务挂了后,
需要手动重启服务
,才气保证这一部分消息能正常消费。
1.2镜像集群
这种模式是在普通集群模式基础上的一种增强方案,这也就是RabbitMQ的官方HA高可用方案。需要在搭建了普通集群之后再增补搭建。其本质区别在于,
这种模式会在镜像节点中央自动进行消息同步
,而不是在客户端拉取消息时临时同步。
在
集群内部有一个算法会推举产生master和slave,当一个master挂了后,也会自动选出一个来
。从而给整个集群提供高可用能力。
这种模式的消息可靠性更高,
因为每个节点上都存着全量的消息
。而他的毛病也是显着的,集群内部的网络带宽会被这种同步通讯大量的斲丧,进而降低整个集群的性能。这种模式下,队列数目最好不要过多。
2.RabbitMQ如何保证消息不丢失
2.1那些环节会有丢失消息的大概?
在上图中,
1,2,4三个场景都是跨网络的,而跨网络就肯定会有丢消息的大概
。
然后
关于3这个环节,通常MQ存盘时都会先写入操作系统的缓存page cache中,然后再由操作系统异步的将消息写入硬盘
。这个
中央有个时间差
,就大概会造成消息丢失。如果服务挂了,
缓存中还没有来得及写入硬盘的消息就会丢失
。这也是任何用户态的应用步伐无法制止的。
2.2RabbitMQ消息零丢失方案
2.2.1生产者保证消息正确发送到RabbitMQ
对于单个消息,使用
生产者确认机制
。
RabbitMQ的生产者确认机制分为
同步确认和异步确认
。
同步确认
重要是通过在生产者端
指定一个等待确认的完成时间
。
异步确认机制
则是通过在生产者端注入
两个回调确认函数
。
第一个函数是在生产者消息发送乐成时调用,第二个函数则是生产者消息发送失败时调用
。两个函数需要通过sequenceNumber自行完成消息的前后对应。sequenceNumber的天生方式需要通过channel的序列获取。int sequenceNumber = channel.getNextPublishSeqNo();
当前版本的RabbitMQ,可以在Producer中添加一个
ReturnListener
,
监听那些乐成发到Exchange,但是却没有路由到Queue的消息
。
如果发送
批量消息,在RabbitMQ中,别的还有一种手动事务
的方式,可以保证消息正确发送。
2.2.2RabbitMQ存盘不丢消息
对于Classic经典队列,直接
将队列声明成为恒久化队列
即可。而新增的Quorum队列和Stream队列,都是显着的恒久化队列,能更好的保证服务端消息不会丢失。(
同步存盘
和异步存盘)(制止不了OS刷盘时服务器宕掉丢数据)
2.2.3RabbitMQ主从消息同步不丢消息
起首他的普通集群模式,消息是分散存储的,不会自动进行消息同步了,是有大概丢失消息的。而镜像模式集群,数据会自动在集群各个节点当中同步,这时丢失消息的概率不会太大。
尽量使用镜像集群
。
2.2.4RabbitMQ消费者不丢消息
RabbitMQ在
消费消息时可以指定是自动应答,还是手动应答
。如果是
自动应答
模式,消费者会在完成业务处理后自动进行应答,而如果消费者的业务逻辑抛出异常,RabbitMQ会将消息进行重试,这样是不会丢失消息的,但是有大概会造成消息一直重复消费。
而将RabbitMQ的应答模式设定为
手动应答
可以进步消息消费的可靠性。
3.如何保证消息幂等
产生原因:RabbitMQ的
自动重试功能导致重复消费消息
。默认环境下,RabbitMQ会无限次数的重复进行消息消费。
办理方案:
1)
设定RabbitMQ的重试次数
,不要让其进行无限次数的重试;
2)
在业务上处理幂等问题
:处理幂等问题的关键是要
给每个消息一个唯一的标识
。 在SpringBoot框架集成RabbitMQ后,可以
给每个消息指定一个全局唯一的MessageID
,在
消费者端针对MessageID做幂等性判定
。在RabbitMQ中,消息的头部就是一个很好的携带数据的地方。
4.如何保证消息的顺序
在RabbitMQ当中,针对消息顺序的设计实在是比力弱的。唯一比力好的策略就是
单队列+单消息推送
。 即一组有序消息,只发到一个队列中,利用队列的FIFO特性保证消息在队列内顺序不会乱。
然后在消费者进行消费时,
保证只有一个消费者
,同时指定prefetch属性为1,即
每次RabbitMQ都只往客户端推送一个消息
。
在多队列环境下,如何保证消息的顺序性,现在使用RabbitMQ的话,还没有比力好的办理方案。
5.关于RabbitMQ的数据堆积问题
如果出现了消息堆积比力严峻的场景,就需
要从数据流转的各个环节综合思量
。
起首在
消息生产者端
:对于生产者端,最显着的方式自然是
降低消息生产的速度
。但是,生产者端产生消息的速度通常是跟业务息息相关的,一般环境下不太好直接优化。但是可以选择尽量
多接纳批量消息的方式,降低IO频率
。
然后在
RabbitMQ服务端
: 从前面的分享中也能看出,RabbitMQ本身实在也在着力于进步服务端的消息堆积能力。
对于消息堆积严峻的队列,可以预先添加懒加载机制,或者创建Sharding分片队列,这些措施都有助于优化服务端的消息堆积能力
。别的,
尝试使用Stream队列,也能很好的进步服务端的消息堆积能力
。
接下来在
消息消费者端
:要提升消费速度最直接的方式,就是
增加消费者数目
了。尤其当消费端的服务出现问题,已经有大量消息堆积时。这时,可以尽量多的申请呆板,部署消费端应用,争取在最短的时间内消费掉积存的消息。但是这种方式需要留意对其他组件的性能压力。
当确实碰到紧急状况,来不及调解消费者端时,可以
紧急上线一个消费者组
,专门用来将消息快速转录。生存到数据库或者Redis,然后再慢慢进行处理。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4