代码之家  ›  专栏  ›  技术社区  ›  Unknown

如何在rabbitmq服务器上设置超时检测?

  •  17
  • Unknown  · 技术社区  · 15 年前

    我在尝试 RabbitMQ 具有 this python绑定。

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

    例如,如果您一次杀死消费者并重新连接,那么1/2消息将被忽略。如果您杀死另一个消费者,那么2/3的消息将被忽略。如果你杀死了第三条,那么3/4条消息将被忽略,以此类推。

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

    有更好的办法吗?

    如何重新创建此方案

    • 运行rabbitmq。

    • 未归档 this library .

    • 下载消费者和发布者 here . 运行amqp_consumer.py两次。运行amqp_publisher.py,输入一些数据并观察其是否按预期工作。消息是按循环方式接收的。

    • 使用kill-9或任务管理器终止一个使用者进程。

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

    3 回复  |  直到 15 年前
        1
  •  11
  •   Tony Garnock-Jones    15 年前

    我看不见 amqp_consumer.py amqp_producer.py 在tarball中,因此再现错误是很棘手的。

    rabbitmq终止连接,在操作系统通知套接字已关闭时,释放未确认的消息以重新传递给其他客户端。你的症状很奇怪,甚至 kill -9 应该导致TCP套接字被正确清理。

    有些人注意到,当在amqp客户机和服务器之间使用防火墙或nat设备运行时,套接字的生存时间比应该的长。这可能是一个问题,或者您正在本地主机上运行所有内容?另外,您在哪个操作系统上运行系统的各个组件?

    埃塔: 从您下面的评论中,我猜当您在linux上运行服务器时,您可能在windows上运行客户机。如果是这种情况,则可能是windows tcp驱动程序没有正确关闭套接字,这与unix上的kill-9行为不同。(在UNIX上,内核将正确地关闭任何已终止进程上的TCP连接。)

    如果是这样,那么 坏消息 RabbitMQ只能在套接字关闭时释放资源,所以如果客户端操作系统不这样做,它就无能为力。这与其他几乎所有基于tcp的服务都是一样的。

    这个 好消息 不过,amqp在这些情况下支持“心跳”选项,因为在这些情况下,网络结构是不可信的。你可以试着激活心跳。当它们被启用时,如果服务器在一个可配置的时间间隔内没有接收到任何流量,它将决定连接必须是死的。

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

        2
  •  5
  •   Vinay Sajip    15 年前

    rabbitmq在客户端确认消息已被处理时没有超时:请参阅 this post (整个线索可能很有趣)。帖子中的一些要点:

    订阅的amqp ack模型 “拉”和“拉”是一样的。在两者 如果消息保存在 服务器,但对其他服务器不可用 消费者直到 确认(并被移除),确认 (带basic.reject;尽管rabbitmq 不实现)或 通道/连接关闭 消息变为可用的点 对其他消费者)。

    (我的重点)

    等待没有超时 阿克斯。通常这不是问题 因为常见的失踪案件 ack-网络或客户端故障- 将导致连接获取 下降 (从而触发 上述行为)。仍然, 一个超时可能有用,比如说, 处理 活着却没有反应 消费者 . 已经进来了 之前的讨论。有什么特别的吗 你要记住的用例 需要这样的功能?

    这个问题很可能发生,因为在客户机拉取模型中,服务器很难检测到断开的连接(而不是活动但无响应的消费者),特别是服务器似乎乐于永远等待ack。

    更新: 在linux上,您可以附加sigterm和/或sigkill和/或sigint的信号处理程序,并希望以一种有序的方式从客户端关闭连接。在windows上,我相信从任务管理器关闭会调用win32 TerminateProcess API,关于它,MSDN说:

    如果进程终止于 终端进程 ,的所有线程 进程立即终止 没有机会运行额外的代码。 这意味着线程没有 在终止处理程序中执行代码 阻碍。此外,没有附加的dll 被告知该过程是 拆卸。

    这意味着可能很难有秩序地终止和关闭。

    可能值得在rabbitmq列表中使用您自己的ack超时用例。

        3
  •  2
  •   yawn    15 年前

    请提供有关您声明的组件的更多详细信息。通常(独立于客户机实现)一个具有属性的队列

    • 独家和
    • 自动删除

    一旦声明客户端和代理之间的连接断开,就应该被删除。不过,这对共享队列没有帮助。请详细说明你到底想做什么样的模特。