【问题标题】:How reliable is BasicPublish()?BasicPublish() 的可靠性如何?
【发布时间】:2019-09-09 05:58:26
【问题描述】:

背景

我正在使用带有 C# 的 RabbitMQ。我有一个包含一个发布者和一个消费者的远程队列。这就是我将消息排入队列(发布者)的方式:

model.BasicPublish(exchange, routingKey, basicProperties, body);

我刚刚发现这个调用总是成功的(成功 = 没有报告错误,异常)。例如,即使我没有连接到网络(队列无法访问) - 它仍然通过这条线并且我不知道它。

问题:

在复杂系统中,可靠性高于一切。那么如何确定消息是否已入队呢?

我认为这一定是一种机制:

  1. 重试时重试消息队列插入
  2. 报告系统会在生产者丢弃消息之前给出报告(不会再次尝试)。

可能的解决方案

我看到here 说我可以实现类似事务的东西,这使得调用原子化并且在出现错误时也会报告。对我来说,它看起来像“太大的锤子”。事务对性能有很大影响。

【问题讨论】:

    标签: c# rabbitmq queue


    【解决方案1】:

    好的。找到了解决方案。

    关于可能的解决方案#1:

    取自 RabbitMQ 文档 (source):

    使用标准的 AMQP 0-9-1,唯一保证一条消息 不会丢失是通过使用事务——使通道具有事务性 然后为每条消息或一组消息发布、提交。在这个 在这种情况下,交易是不必要的重量级和减少 吞吐量增加了 250 倍。为了解决这个问题,确认 引入了机制。它模仿了消费者的确认 协议中已经存在的机制。

    根据这篇文章,正确的解决方案是使用“Publisher confirms”。基于this answer,我要做的就是:

    channel.BasicPublish(QUEUE_NAME, QUEUE_NAME, messageProperties, payload);
    channel.WaitForConfirmsOrDie();
    

    【讨论】:

    • channel.WaitForConfirmsOrDie() 是同步的,会严重限制性能。 this tutorial 中描述的技术也适用于 .NET 客户端库 - 您应该阅读它。
    • 有趣。感谢分享。
    猜你喜欢
    • 2012-05-19
    • 2015-07-21
    • 2011-05-05
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    相关资源
    最近更新 更多