Rabbitmq 中, acknowledge-mode 配置为 auto,消费会丢失数据吗?

208 天前
 vanpeisi7
使用 rabbitmq 的 consumer 的 autoAck 进行消费,什么场景下会丢失数据。我用 springboot 整合 rabbitmq ,使用 SimpleMessageListenerContainer 进行消费,并没有模拟出来丢失数据的场景。我发现,如果配置了 autoAck,SimpleMessageListenerContainer 在 commitIfNecessary 内使用 channel 进行 ack 了。这自己手动调用 channel 进行 ack 有什么区别吗?
694 次点击
所在节点    程序员
4 条回复
wolfie
208 天前
区别再于,开始消费到手动 ack 有没有 exception 。
vanpeisi7
208 天前
@wolfie 我理解的主要区别,就是 manaul 手动 ack ,如果出现异常,可以进行捕获,然后进行 basicNack ,basicNack 时候,requeue 设置为 true ,消息会重回队列。出现异常时,消息一直不断的消费和 requeue 进入队列,这样能保证消息不丢失。如果是 autoAct ,出现异常,没法做特殊处理,然后被 SimpleMessageListenerContainer 自动 ack 掉了。如果使用 autoAck,出现异常也进行捕获,然后对异常做处理(比如循环重试,直到成功),这样是否也能保证不丢失消息。
UltraXiaoZi
208 天前
如果你用的是 spring-rabbitmq ,自动模式不会丢失数据,抛出异常后消息会回退,这个你可以自己试一下就知道了,和手动确认的唯一区别是 spring 封装了一个异常类,如果不想出现异常,就抛出 AmqpRejectAndDontRequeueException ,另外你可以看一下 org.springframework.amqp.core.AcknowledgeMode 的注释

/**
* Auto - the container will issue the ack/nack based on whether
* the listener returns normally, or throws an exception.
* <p><em>Do not confuse with RabbitMQ {@code autoAck} which is
* represented by {@link #NONE} here</em>.
*/
AUTO;

明确告诉你了,这里面的 AUTO 并不是 rabbitmq 中的 auto ,本质上也是手动,只是被 spring 封装了一层,当然你也可以用手动,但是那样对代码的侵入性太高了,而且这种这种通用处理一般建议是抽离到业务代码之外,便于全局控制和保持一致的处理方式,除非你有非常特别的用需要使用 channel 进行操作
vanpeisi7
208 天前
@UltraXiaoZi 原来如此,终于明白了,我原以为 spring-rabbitmq 和 rabbitmq 中的 auto 是一样的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/985593

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX