2009-08-28 109 views
17

我尝试RabbitMQthis Python绑定。如何设置的RabbitMQ服务器超时检测?

我注意到的一件事是,如果我不洁地杀死一个消费者(模拟一个崩溃的程序),服务器会认为这个消费者仍然存在很长时间。这样做的结果是每个其他消息都将被忽略。

例如,如果您杀死消费者1次并重新连接,则1/2消息将被忽略。如果你杀了另一个消费者,那么2/3消息将被忽略。如果你杀了3,然后3/4的邮件都将被忽略等等。

我试着打开确认,但似乎并没有被帮助。我发现的唯一解决方案是手动停止服务器并重置它。

有没有更好的方法?

如何重建这种情况下

  • 运行的RabbitMQ。

  • 取消存档this library

  • 下载消费者和发行商here。 运行amqp_consumer.py两次。运行amqp_publisher.py,在一些数据反馈,并观察它按预期工作。消息以循环方式接收。

  • 用kill -9或任务管理器杀死其中一个消费者进程。

  • 现在,当您发布消息时,50%的消息将会丢失。

+0

我更新了我的答案。 – 2009-09-06 10:48:26

+0

我无法复制此内容。你使用的是什么版本的 – 2010-02-03 13:24:34

+3

好问题 - 如果在防火墙或IP负载平衡设备后运行,在N秒后丢弃空闲套接字,这是一个关键问题,因为RabbitMQ和客户端都不会被告知套接字已经消失直到他们尝试使用它。 – 2011-05-07 14:00:26

回答

2

请提供一些关于您声明的组件的更多细节。通常(和独立的客户端实现的)与性质

  • 独家和队列
  • 自动删除

应该得到尽快移除申报客户端与代理之间的连接分手。尽管如此,这对于共享队列并无帮助。请详细介绍一下你正在试图建模的东西。

+0

我不是在说什么时候队列被删除。我正在谈论rabbitmq如何在很长一段时间内没有检测到崩溃的连接,并一直试图发送消息,好像它们仍在那里。 – Unknown 2009-09-04 19:23:18

5

RabbitMQ没有来自客户端的消息已处理的确认超时:请参阅this post(整个线程可能是感兴趣的)。从帖子的一些要点:用于订阅

的AMQP确认模型和“拉”是相同的。在 这两种情况下,邮件保留在 服务器上,但对其他 使用者不可用,直到它已被确认(并被删除) ,缺陷 (含基本。拒绝;尽管RabbitMQ 没有实现该功能)或 通道/连接已关闭(其中 指向其他客户的消息变为可用 )。

和(我的重点)

有上等待 的ACK没有超时。通常这不是一个问题,因为 缺少 ACK的常见的情况- 网络或客户端失败 - 将导致越来越 下降(并且因此触发上述 行为)的连接。 暂停可能会有用,例如, 处理活着但无响应 消费者。这已经在 之前讨论过了。有没有一个特定的 用例请记住 需要这样的功能?

的问题很可能是出现因为客户端拉模式,它很难服务器来检测断开的连接(而不是一个还活着,但反应迟钝消费者),尤其是在服务器似乎乐意永远等待ack。

更新:在Linux上,您可以附加SIGTERM和/或SIGKILL和/或SIGINT的信号处理程序,并希望从客户端有序地关闭连接。在Windows上,我相信从任务管理器关闭调用Win32的TerminateProcess API,对此MSDN说:

如果一个进程被 TerminateProcess终止, 进程的所有线程立即 终止,没有机会跑额外的代码。 这意味着线程不会在终止处理程序 块中执行代码 。另外,没有附加的DLL 被通知该过程是 分离。

这意味着可能难以以有序的方式捕捉终止并关闭。

这可能是值得追求的RabbitMQ列表与你自己的用例一个确认超时。

+0

根据该邮件列表,如果消费者终止连接,它应该正常运行。但是,kill -9或taskmanager中的结束进程也应以此方式终止连接。但它仍然无法正常工作。 – Unknown 2009-09-06 00:46:24

11

我没有在tarball中看到amqp_consumer.pyamqp_producer.py,所以重现错误是棘手的。

RabbitMQ终止连接,只要操作系统告知套接字已关闭,RabbitMQ就会释放它们的未确认消息以重新传递给其他客户端。你的症状很奇怪,因为即使是一个kill -9应该导致TCP套接字被正确地清理。

有些人注意到套接字存在的问题比在AMQP客户端和服务器之间使用防火墙或NAT设备运行时要长。这可能是一个问题,或者你在本地主机上运行的一切?此外,你在运行系统的各种组件的操作系统是什么?

ETA:从下面的评论,我猜测,而你是在Linux上运行的服务器,你可能会在Windows上运行的客户端。如果是这种情况,那么可能是Windows TCP驱动程序没有正确关闭套接字,这与Unix上的kill-9行为不同。 (在Unix上,内核将正常关闭任何杀死进程的TCP连接。)

如果是这样的话,那么坏消息是,当关闭套接字的RabbitMQ只能释放资源,因此,如果客户端操作系统并没有这样做,没有什么可以做的。这与几乎所有其他基于TCP的服务都是一样的。

好消息,但是,AMQP支持一个“心跳”选项,正是这些情况下,网络结构是不可信的。你可以尝试启用心跳。当它们被启用时,如果服务器在可配置的时间间隔内没有收到任何流量,它会判定连接已经死机。

坏消息,但是,我不认为py-amqplib目前支持心跳。值得一试,但!

+0

对不起。生产者和消费者在这里http://blogs.digitar.com/jjww/code-samples/ – Unknown 2009-09-06 18:43:14

+0

我在远程linux服务器上运行rabbitmq,同时运行生产者和消费者。我意识到套接字可能没有完全关闭,但这正是我想要模拟的。我正在测试以查看rabbitmq如何处理崩溃的进程,这些进程可能没有完全关闭套接字,不幸的是,它似乎无法处理得很好。 – Unknown 2009-09-06 18:46:50

+1

@Tony;如何启用RabbitMQ服务器中的“心跳”选项(例如/etc/rabbitmq/rabbitmq.config中)? – 2010-02-16 03:04:07