如何优雅地与rabbitmq队列断开连接

问题描述 投票:0回答:1

我的rabbitmq 客户端遇到了竞争状况问题。我的服务有多个实例侦听单个队列,将收到的消息存储到数据库中。

当它们全部重新启动时,我有时会看到消息被重新传递并存储在数据库中两次。这通常在客户端通过检查关联 ID 是否已存储在数据库中来处理。这在 99.9% 的时间里有效(我每天处理 500 万条消息,每天发生一两次)。

正如我所说,我怀疑这是赛车状况造成的。我想我在第一条消息仍在处理时再次收到该消息。因此,当我检查时,我没有看到它存储在数据库中,最后,将其存储两次。

我不应该认为这不是问题,但一直困扰着我,因为我无法真正解释发生了什么。

我怀疑当我重新启动服务时会发生这种情况。我想我与队列断开连接,同时我仍在处理消息,触发rabbitmq再次重新传递到另一个尚未关闭的实例。

我想做的是当我停止服务时

  • 告诉rabbitmq我不想再收到消息了
  • 等待所有当前正在处理的消息完成
  • 发送ack/nacks
  • 关机

现在我首先注销收到的事件

_consumerServer.Received -= MessageReceived;

然后我正在处理频道和服务器

        if (_channel != null)
        {
            _channel.Close();
            _channel.Dispose();
        }

        if (_connectionServer != null)
        {
            _connectionServer.Close();
            _connectionServer.Dispose();
        }
c# rabbitmq windows-services
1个回答
1
投票

您应该正确处理重新传递,而不是尝试关闭消费者以使消息不会被重新传递。检查并处理消息上设置了

redelivered
标志的情况,并采取适当的措施。您还应该尝试以存储操作幂等的方式存储消息 - 即它可以发生多次,并且数据库中只有一条记录。

请参阅团队在此处提供的指南:

https://www.rabbitmq.com/reliability.html#consumer

© www.soinside.com 2019 - 2024. All rights reserved.