使用RabbitMQ常见问题

在使用RabbitMQ过程中,我们会遇到一些常见问题,总结如下:

一:RabbitMQ如何保证消息不丢失

回答这个问题之前,先考虑下MQ涉及到了哪些场景;
使用RabbitMQ常见问题_第1张图片
如上图,1,2,4进行了网络交互信息传递,就会造成信息丢失。
1)生产者保证消息正确发送到RabbitMQ
生产者确认机制分为同步确认和异步确认。同步确认主要是通过在生产者端使用Channel.waitForConfirmsOrDie()指定一个等待确认的完成时间。异步确认机制则是通过两个回调确认。
使用手动事务的方式,可以保证消息的正确发送。
2)RabbitMQ消息存盘不丢失信息
对于Classisc经典队列,直接将队列声明为持久化队列即可;
Quorum队列和Stream队列,都是默认的持久化;
3)RabbitMQ主从消息同步过程不丢失消息
这里涉及到集群架构,如果是普通集群模式,消息时分散存储的,可能丢失;如果是镜像模式,数据会主动在集群各个节点当中同步,丢失的概率不高。
4)RabbitMQ消费者不丢失消息
消费消息时,可以指定是自动应答还是手动应答;如果自动应答,消费者会在完成业务后自动进行应答,如果有抛出异常则会重试,但是会可能会导致消息的重复消费;
设置为手动应答,可以提高消息消费的可靠性;

二:如何保证消息幂等性

RabbitMQ的自动重试功能:
当消费者消费消息处理业务逻辑时,如果抛出异常,或者不向RabbitMQ返回响应,默认情况下,RabbitMQ会无限次数的重复进行消息消费。
1)处理幂等性问题,首先要设定RabbitMQ的重试次数。
2)业务上处理幂等性问题;

三:如何保证消息的顺序

在某些场景,需要消息进行顺序的消费。
RabbitMQ对于顺序消费这块设计的比较弱。比较好一点的方法是,单队列+单消息推送。

四:RabbitMQ的数据堆积问题

对于消息堆积的问题,当有大量数据时,整体性能会下降。新版Quorum队列和Stream队列就是主要处理这个问题;
围绕生产者端:降低生产消息的速度
服务端:添加懒加载机制,或者队列分片;
消费端:增加消费者数量

# 单次推送消息数量
spring.rabbitmq.listener.simple.prefetch=1
# 消费者的消费线程数量
spring.rabbitmq.listener.simple.concurrency=5

总结:

基于MQ的事件驱动机制,给庞大的互联网应用带来了不一样的方向。MQ的异步、解耦、削峰三大功能特点在很多业务场景下都能带来极大的性能提升,在日常工作过程中,应该尝试总结这些设计的思想。

你可能感兴趣的:(消息中间件,java-rabbitmq,rabbitmq,分布式)