我的rabbitmq 客户端遇到了竞争状况问题。我的服务有多个实例侦听单个队列,将收到的消息存储到数据库中。
当它们全部重新启动时,我有时会看到消息被重新传递并存储在数据库中两次。这通常在客户端通过检查关联 ID 是否已存储在数据库中来处理。这在 99.9% 的时间里有效(我每天处理 500 万条消息,每天发生一两次)。
正如我所说,我怀疑这是赛车状况造成的。我想我在第一条消息仍在处理时再次收到该消息。因此,当我检查时,我没有看到它存储在数据库中,最后,将其存储两次。
我不应该认为这不是问题,但一直困扰着我,因为我无法真正解释发生了什么。
我怀疑当我重新启动服务时会发生这种情况。我想我与队列断开连接,同时我仍在处理消息,触发rabbitmq再次重新传递到另一个尚未关闭的实例。
我想做的是当我停止服务时
现在我首先注销收到的事件
_consumerServer.Received -= MessageReceived;
然后我正在处理频道和服务器
if (_channel != null)
{
_channel.Close();
_channel.Dispose();
}
if (_connectionServer != null)
{
_connectionServer.Close();
_connectionServer.Dispose();
}
您应该正确处理重新传递,而不是尝试关闭消费者以使消息不会被重新传递。检查并处理消息上设置了
redelivered
标志的情况,并采取适当的措施。您还应该尝试以存储操作幂等的方式存储消息 - 即它可以发生多次,并且数据库中只有一条记录。
请参阅团队在此处提供的指南: