RabbitMQ常见问题总结
一、如何保证消息不丢失?
首先分析哪些环节可能会出现消息丢失:生产者发消息、消息存盘、主从数据同步、消费消息。1. 生产者发消息
通过多次确认的方式来确保消息一定能发送到RabbitMQ中。如通过channel.addConfirmListener(cb1, cb2)。第一个回调是发完消息时调用,第二个回调是收到服务端反馈请求时调用。
2. 消息存盘
这个在RabbitMQ中比较好处理,对于Classic经典队列,直接将队列声明成为持 久化队列即可。而新增的Quorum队列和Stream队列,都是明显的持久化队列,能更好的保证服务端消息不会丢失。数据保存是由操作系统实现的,首先是保存到Page Cache再由操作系统刷盘,这期间如果断电是会丢数据的。
3. 主从数据同步
这涉及到RabbitMQ的集群架构。首先他的普通集群模式,消息是分散存储的, 不会主动进行消息同步了,是有可能丢失消息的。而镜像模式集群,数据会主动在 集群各个节点当中同步,这时丢失消息的概率不会太高。
另外,启用Federation联邦机制,给包含重要消息的队列建立一个远端备份,也是一个不错的选择。
4. 消费消息
手动ACK,避免消费时抛出异常了还ACK。
任何用户态的应用程序都无法保证绝对的数据安全,要准备备份与恢复方案。
二、如何保证消息幂等?
给每条消息一个唯一标识,通过标识来判断是否已处理过。如在Spring Boot中给Message设置messageId为订单ID。三、如何保证消息的顺序?
RabbitMQ中只能是让需要有序的消息进同一个队列,然后消费时也只能有一个消费者。如果对性能又有比较高的要求,那么相同类型的队列可以创建多个,然后依然是每一个队列一个消费者即可。最好是避免这种场景让RabbitMQ来做。四、数据堆积问题
在消息生产者端,多采用批量消息的方式,降低IO频率。在RabbitMQ服务端,对于消息堆积严重的队列,可以预先添加懒加载机制,或者创建Sharding 分片队列,这些措施都有助于优化服务端的消息堆积能力。另外,尝试使用Stream 队列,也能很好的提高服务端的消息堆积能力。
在消息消费者端,增加消费者数量,对于单个消费者端,可以通过配置提升消费者端的吞吐量。如:
#单次推送消息数量当确实遇到紧急状况,来不及调整消费者端时,可以紧急上线一个消费者组,专 门用来将消息快速转录。保存到数据库或者Redis,然后再慢慢进行处理。
spring.rabbitmq.listener.simple.prefetch=1
#消费者的消费线程数量
spring.rabbitmq.listener.simple.concurrency=5
五、RabbitMQ的备份与恢复
1. 控制台导出导入元数据json文件2. rabbitmqctl status查看消息数据文件存储目录,先停止所有rabbitmq服务,复制即可。
六、高可用集群
keepAlived故障转移 + HAProxy负载均衡以上总结自互联网
2023/12/01 15:06