永不结束消息循环:在python rabbitmq consumer

时间:2015-11-16 15:40:15

标签: python rabbitmq pika

我正在使用此处发布的示例消费者:

http://pika.readthedocs.org/en/latest/examples/asynchronous_consumer_example.html

我使用ExampleConsumer的原因是我与rabbitmq的连接在工作任务开始花费更长时间时失败,其中更长时间超过10分钟。在长时间运行的任务完成并且该过程失败后,该连接正在关闭。它以前经历了1000条消息,花了一分钟左右。

ExampleConsumer似乎重新连接正常,但是,在确认消息中,消息实际上没有被确认,因为连接已经死亡。它似乎从下面的确认消息方法正常返回。然后尝试重新连接,之后重新传递刚刚完成的消息。

  def acknowledge_message(self, delivery_tag):
        """Acknowledge the message delivery from RabbitMQ by sending a
        Basic.Ack RPC method for the delivery tag.

        :param int delivery_tag: The delivery tag from the Basic.Deliver frame

        """
        LOGGER.info('Acknowledging message %s', delivery_tag)
        self._channel.basic_ack(delivery_tag)

3 个答案:

答案 0 :(得分:1)

RabbitMQ代理实现了一个默认的心跳超时,根据RabbitMQ版本,它可以是~10分钟或1分钟;较短的默认值是在最近的版本中,从RabbitMQ v3.5.5开始。应用程序可以通过连接参数传递显式更长的心跳超时首选项。 Pika的SelectConnection没有后台线程,因此当工作任务花费的时间超过心跳超时时,SelectConnection无法在代理预期的时间限制内为心跳提供服务,并且代理会断开连接。有不同的方法可以尝试解决这个问题:

  1. 通过pika.connection.ConnectionParameters(可能是最简单的)设置更长的心跳超时首选项。 ConnectionParameters.heartbeat_interval = 0应该完全禁用心跳(和心跳超时)。
  2. 在与任务处理逻辑
  3. 不同的线程上运行连接
  4. 切换到其中一种协作式多任务连接类型,例如Pika中的Tornado或Twisted基于框架的适配器,或者Haigha中基于gevent的适配器。此更改将要求任务处理逻辑对协作式多任务处理友好。

答案 1 :(得分:0)

您可能需要add a heartbeat to your message consumer才能保持连接的正常运行。

如果rabbitmq认为消费者在消息处于“未确认”模式(仍在处理)时死亡,则会将消息放回队列中。心跳可能有助于保持连接的存在,防止这种情况发生。

答案 2 :(得分:0)

如果您使用的是pika异步使用者示例,则只需将此更改添加到init方法:

    self._url = 'amqp://{}:{}@{}:{}/%2F{}'.format(
                     self.USERNAME, self.PASSWORD, self.ADDRESS, self.PORT, self.QUERY) 

使用self.QUERY一个字符串,可以参数化以设置不同的参数,例如心跳如下:

self.QUERY ='?heartbeat_interval=600'

connect方法将处理心跳事务。

def connect(self):
    """This method connects to RabbitMQ, returning the connection handle.
    When the connection is established, the on_connection_open method
    will be invoked by pika.

    :rtype: pika.SelectConnection

    """
    LOGGER.info('Connecting to %s', self._url)
    return pika.SelectConnection(parameters=pika.URLParameters(self._url),
                                 on_open_callback=self.on_connection_open,
                                 on_open_error_callback=self.on_connection_error,
                                 stop_ioloop_on_close=False,
                                 )

这是告诉RabbitMQ哪个心跳与您的消费者关联的一种非常好的方式。请注意,RabbitMQ将强制它至少60秒。因此,您无法将其设置得更低。

有关这些连接参数的更多信息: https://pika.readthedocs.io/en/latest/modules/parameters.html