0

Publisher Confirms上的 RabbitMQ 博客文章说

如果发布者和代理之间的连接因未完成的确认而断开,这并不一定意味着消息丢失,因此重新发布可能会导致重复消息。

这意味着IModel.WaitForConfirmsOrDie()当与代理的连接在等待 时断开时,将引发异常(就像确认的快速测试一样)Ack,但消息可能仍会被传递。有没有办法通过查看异常来区分是否

  1. 消息肯定没有送达
  2. 消息可能已送达

换句话说,有没有办法明确区分所有(可能的)Nacks(=未传递)与其他错误,如连接断开(在代理接受消息之后)?

API 文档只说

如果收到 nack,立即抛出 OperationInterruptedException 异常

在我的“断开连接”测试中,也抛出了一个(源自)OperationInterruptedException 的异常,因此这似乎排除了仅查看异常类型的可能性。

4

1 回答 1

1

查看源代码(.net 客户端 3.1.3),文档似乎不太准确,因为IOException在 Nacks 的情况下会被抛出,如果你问我,这是一个相当奇怪的选择:

public void WaitForConfirmsOrDie(TimeSpan timeout)
{
    bool timedOut;
    bool onlyAcksReceived = WaitForConfirms(timeout, out timedOut);
    if (!onlyAcksReceived) {
        ...
        throw new IOException("Nacks Received");
    }

不幸的是,这只是源代码,并且规范(在 api 文档中)有所不同。无论如何,看起来我目前可以这样做:

bool definitelyNotSend = e is IOException && "Nacks Received".Equals(e.Message);

然而,除了 Nacks 之外,还有一些例外情况可能会发生,这意味着消息肯定没有被发送,比如发送到不存在的交换器时。在这种情况下,你会得到一个AlreadyClosedException404 的ShutdownReason.ReplyCode结果。

编辑:我在https://stackoverflow.com/a/18117000/709537中的测试证实上述 IOException 实际上被抛出。

于 2013-08-07T08:36:33.567 回答