我正在调用:
GetResponse response = channel.basicGet("some.queue", false); // no auto-ack
....
channel.basicAck(deliveryTag, ...);
但是,当我调用 basicGet
时,队列中的消息保持“就绪”状态,而不是“未确认”状态。我希望它们处于未确认状态,这样我就可以 basic.ack
它们(从而从队列中丢弃它们),或者 basic.nack
它们
最佳答案
我正在执行以下操作来模仿延迟确认:
消费时
- 从初始队列中获取(使用)消息。
- 创建“PendingAck_123456”队列。
123456是消息的唯一ID。
设置以下属性- x-message-ttl(在之后重新排队 超时)
- x-expires(以确保临时队列将被删除)
- x-dead-letter-exchange 和 x-deal-letter-routing-key 来重新排队 TTL 到期时的初始队列。
- 将消息 Pending ack 发布到此“PendingAck_123456”队列
- 确认消息并将其从初始队列中删除
在确认时间
- 根据消息 ID 计算队列名称并从“PendingAck_123456”队列中获取
- 确认(无需调用
.getBody()
)。
这会将其从待处理队列中删除,从而防止 TTL 将其重新排队
备注
- 一个队列仅包含 1 条消息。如果有很多这样的队列,这会是一个问题吗?
- 重新排队的消息将在队列输入端发送。而不是在队列输出端(如真正的确认那样)。这会对消息顺序产生影响。
- 消息由应用程序复制到待处理队列。这是一个可能会影响整体性能的额外步骤。
- 要模拟 Nack/Reject,您可能需要将消息复制到初始队列,然后从 PendingAck 队列中确认它。默认情况下,TTL 会执行此操作(稍后)。
关于java - RabbitMQ basic.get 和确认,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7849891/