一、RabbitMQ如何保证消息不丢失
1、哪些环节存在消息丢失的可能
因为1、2、4都是跨网络的,而跨网络就会存在丢失消息的可能。对于3来说,通常MQ存盘时都会先写入操作系统的缓存page cache中,然后再由操作系统异步寸盘。当在异步存盘时如果服务挂了,缓存中还未存盘的消息就会丢失。这是大部分应用程序无法避免的。
对于任何MQ产品,都应该从这四个方面来考虑数据的安全性。
2、RabbitMQ消息零丢失方案
(1)生产者保证消息正确发送到RibbitMQ
(2)RabbitMQ消息存盘不丢消息
对于Classic经典队列,直接将队列声明成为持久化队列即可。而新增的Quorum队列和Stream队列,都是明显的持久化队列,能更好的保证服务端消息不会丢失。
(3)RabbitMQ主从消息同步时不丢消息
如果是镜像模式集群,数据会主动在集群各个节点当中同步,丢失消息的概率不会太高。
如果是普通集群模式,消息是分散存储的,不会主动进行消息同步,是有可能丢失消息的。
可以通过配置autoheal以及启用Federation联邦机制,给包含重要消息的队列建立一个远端备份都可以解决。
(4)RabbitMQ消费者不丢失消息
RabbitMQ在消费消息时可以指定是自动应答,还是手动应答。如果是自动应答模式,消费者会在完成业务处理后自动进行应答,而如果消费者的业务逻辑抛出异常,RabbitMQ会将消息进行重试,这样是不会丢失消息的,但是有可能会造成消息一直重复消费。将RabbitMQ的应答模式设定为手动应答可以提高消息消费的可靠性。
二、如何保证消息幂等
RabbitMQ服务端:要设定RabbitMQ的重试次数,制定重试策略。因为当消费者消费消息处理业务逻辑时,如果抛出异常,或者不向RabbitMQ返回响应,默认情况下,RabbitMQ会无限次数的重复进行消息消费。
消费端:处理幂等问题的关键是要给每个消息一个唯一的标识。在SpringBoot框架集成RabbitMQ后,可以给每个消息指定一个全局唯一的MessageID,在消费者端针对MessageID做幂等性判断。可以查库判断、或者借用布隆过滤器等redis高级数据结构。
三、如何保证消息的顺序
某些场景下,需要保证消息的消费顺序,例如一个下单过程,需要先完成扣款,然后扣减库存,然后通知快递发货,这个顺序不能乱。如果每个步骤都通过消息进行异步通知的话,这一组消息就必须保证他们的消费顺序是一致的。
在RabbitMQ当中,针对消息顺序的设计其实是比较弱的。唯一比较好的策略就是单队列+单消息推送。即一组有序消息,只发到一个队列中,利用队列的FIFO特性保证消息在队列内顺序不会乱。然后在消费者进行消费时,保证只有一个消费者,同时指定prefetch属性为1,即每次RabbitMQ都只往客户端推送一个消息。但是这是以极度消耗性能作为代价的,在实际适应过程中,应该尽量避免这种场景
而在多队列情况下,如何保证消息的顺序性,目前使用RabbitMQ的话,还没有比较好的解决方案。在使用时,应该尽量避免这种情况。
四、RabbitMQ的数据堆积问题
RabbitMQ一直以来都有一个缺点,就是对于消息堆积问题的处理不好。当RabbitMQ中有大量消息堆积时,整体性能会严重下降。目前新推出的Quorum队列以及Stream队列,目的就在于解决这个核心问题。但是这两种队列的稳定性和周边生态都还不够完善,因此在使用RabbitMQ时,还是要非常注意消息堆积的问题。尽量让消息的消费速度和生产速度保持一致。
五、RabbitMQ的备份与恢复
对于消息,由于MQ的特性,是不建议进行备份恢复的。
恢复数据步骤:
六、RabbitMQ的性能监控
关于RabbitMQ的性能监控,在管理控制台中提供了非常丰富的展示。例如在下面这个简单的集群节点图中,就监控了非常多系统的关键资源,包括消息的生产消费频率、关键组件使用情况等信息。
同时RabbitMQ也提供了一系列的HTTP接口,通过这些接口可以非常全面的使用并管理RabbitMQ的各种功能。在部署的管理控制台页面下方已经集成了详细的文档,只需要打开HTTP API的页面就能看到,通过这个接口,就可以很好的对接Promethus、Grafana等工具,构建更灵活的监控告警体系。
七、搭建HAProxy,实现高可用集群
之前搭建的镜像集群,已经具备了集群的功能,请求发送到任何一个节点上,数据都是在集群内共享的。但是在企业使用时,通常还会选择在集群基础上增加负载均衡的能力。将客户端的请求能够尽量均匀的分配到集群中各个节点上,这样可以让集群的压力得到平衡。
实现负载均衡的方式有很多,HAProxy就是其中一种可选方案。HAProxy是一个免费、快速并且可靠的解决方案,有很多大型互联网公司都在使用。通过HAProxy,应用可以直连一个单一的IP地址,然后HAProxy会将这个IP地址的TCP请求进行转发,并在转发过程中实现负载均衡。
除了HAProxy,还可采用Keepalived和F5,需要根据实际情况而定,适合的才是最好的