Rebus停止从RabbitMQ检索消息

时间:2014-01-07 08:56:05

标签: c# rabbitmq rebus

我们的Rebus / RabbitMQ设置存在问题,Rebus突然停止从RabbitMQ检索/处理消息。这种情况在上个月发生了两次,我们不确定如何继续。

我们的RabbitMQ设置在不同的服务器上有两个节点,Rebus端是一个Windows服务。

我们发现Rebus或Rebus运行的服务器上的事件日志中没有错误。 我们也没有在RabbitMQ服务器上看到错误。

Rebus(以及Windows服务)继续运行,因为我们看到其他日志消息,如DueTimeOutSchedular和timeoutreplies。但是,似乎工作线程停止运行,但没有记录任何错误。

它会导致RabbitMQ输入队列不断增长:(我们正在添加日志记录来监控它,以便我们在再次发生时收到通知。

但我正在寻找有关如何继续“调查”以及如何防止这种情况的想法的建议。也许有些人以前经历过这个?

更新 看来我们确实有一个节点崩溃,至少在最后一次发生时。主RabbitMQ节点崩溃(服务器崩溃),从服务器被提升为主服务器。据我所知,节点上的RabbitMQ日志一切都按计划进行。 RabbitMQ日志中没有其他错误。

在发生这种情况时,Rebus被配置为仅连接到从属节点(然后提升为主节点),因此Rebus没有遇到rabbitmq故障,因此没有Rebus连接错误。但是,似乎Rebus在发生故障时停止处理消息。

我们实际上是在几个队列中遇到这种情况,其中一些,但并非所有队列似乎都处于非同步状态。

更新2 我能够很容易地重现问题,所以它可能是我们设置中的配置问题。但这就是我们重现它的方法

  1. 启动群集中的两个节点,例如 rabbit1 (主人)和 rabbit2 (奴隶)
  2. Rebus连接到 rabbit2 ,奴隶
  3. 关闭 rabbit1 ,即主人。 rabbit2 升级为主人
  4. 队列是镜像的

    我们有两个小测试应用程序来重现这个,一个“发送者”每秒发送一条消息,一个“消费者”处理这些消息。

    rabbit1 关闭时,“使用者”会停止处理邮件,但“发件人”会继续发送邮件并且队列会不断增长。

    1. 再次启动 rabbit1 ,它作为slave
    2. 加入

      这没有效果,“消费者”仍然无法处理消息。

      1. 重新启动“消费者”应用
      2. 当“consumer”重新启动时,它会检索所有消息并处理它们。

        我认为我已正确遵循设置指南,但这可能是我们配置问题。我似乎无法找到任何可能表明我们做错了什么。

        Rebus仍然连接到RabbitMQ,我们看到在管理站点的连接选项卡中,“消费者”发送/接收的B / s在停止处理消息时降至约2 B / s

        更新3 好的,所以我下载了Rebus源并附加到我们的进程,所以我可以看到“RabbitMqMessageQueue”类停止时会发生什么。当“rabbit1 *关闭”时,“BasicDeliverEventArgs”为空,这是代码

        BasicDeliverEventArgs ea;
        if (!threadBoundSubscription.Next((int)BackoffTime.TotalMilliseconds, out ea))
        {
            return null;
        }
        
        // wtf??
        if (ea == null)
        {
            return null;
        }
        

        请参阅:https://github.com/rebus-org/Rebus/blob/master/src/Rebus.RabbitMQ/RabbitMqMessageQueue.cs#L178

        我喜欢“wtf ??”评论:)

1 个答案:

答案 0 :(得分:3)

听起来很奇怪!

每当Rebus的RabbitMQ传输在连接上出现错误时,它将丢弃连接,等待几秒钟,并确保在可能的情况下再次重新建立连接。

您可以在此处查看来源中的相关位置:https://github.com/rebus-org/Rebus/blob/master/src/Rebus.RabbitMQ/RabbitMqMessageQueue.cs#L205

所以我想问的问题是RabbitMQ客户端库是否可以以某种方式静默地进入故障状态,而不会在Rebus尝试获取下一条消息时抛出异常......?

当您遇到错误时,您是否查看了RabbitMQ管理界面中的“连接”标签,看看客户端是否仍然连接?

<强>更新

感谢您彻底调查:)

“wtf ??”是因为我曾经在ea显然为空时经历了一次打嗝,这在当时是意料之外的,因此导致NullReferenceException以后和我的日志中的异常呕吐。

根据the docsNext将返回true并在result到达“end-of-stream”时将其设置为null,这显然是当底层模型是闭合。

在这种情况下Rebus的正确行为是抛出一个正确的异常并重新建立连接 - 我马上就会实现它!

请坐下,我会在几分钟内准备好你的补救措施!