在确认模式下区分Nack和其他错误

时间:2013-08-07 07:45:04

标签: .net rabbitmq confirm

Publisher Confirms上的RabbitMQ博客文章

  

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

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

  1. 消息绝对未送达
  2. 消息可能已经发送
  3. 换句话说,是否有办法明确区分所有(可能可能的)Nack s(=未交付)与其他错误(如断开的连接)(在经纪人接受消息后)?< / p>

    API文档只说

      

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

    在我的'drop connection'测试中,还抛出了一个(异常派生的)OperationInterruptedException,因此似乎只排除了查看异常的类型。

1 个答案:

答案 0 :(得分:1)

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

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 之外还有例外情况,并且暗示邮件肯定没有被发送,例如发送到不存在的交易所时。在这种情况下,您将获得AlreadyClosedException,其中ShutdownReason.ReplyCode为404。

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