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