Python 如何重新连接到RabbitMQ?
我的python脚本从另一个数据源接收消息后,必须不断向RabbitMQ发送消息。python脚本发送它们的频率可能会有所不同,例如,1分钟到30分钟 以下是我如何建立到RabbitMQ的连接:Python 如何重新连接到RabbitMQ?,python,rabbitmq,pika,Python,Rabbitmq,Pika,我的python脚本从另一个数据源接收消息后,必须不断向RabbitMQ发送消息。python脚本发送它们的频率可能会有所不同,例如,1分钟到30分钟 以下是我如何建立到RabbitMQ的连接: rabt_conn = pika.BlockingConnection(pika.ConnectionParameters("some_host")) channel = rbt_conn.channel() 我只是有个例外 pika.exceptions.ConnectionClosed
rabt_conn = pika.BlockingConnection(pika.ConnectionParameters("some_host"))
channel = rbt_conn.channel()
我只是有个例外
pika.exceptions.ConnectionClosed
如何重新连接到它?最好的办法是什么?有什么“策略”吗?是否能够发送ping以保持连接活动或设置超时
任何提示都将受到欢迎。非常简单:一些类似的模式
import time
while True:
try:
communication_handles = connect_pika()
do_your_stuff(communication_handles)
except pika.exceptions.ConnectionClosed:
print 'oops. lost connection. trying to reconnect.'
# avoid rapid reconnection on longer RMQ server outage
time.sleep(0.5)
您可能需要重新考虑您的代码,但基本上它是关于捕获异常、缓解问题并继续执行您的工作。
通信\u句柄
包含所有pika元素,如通道、队列以及您的员工通过pika与RabbitMQ通信所需的任何内容。RabbitMQ使用心跳来检测和关闭“死”连接,并防止网络设备(防火墙等)终止“空闲”连接。从3.5.5版开始,默认超时设置为60秒(以前为10分钟)。从:
心跳帧大约每超时/2秒发送一次。错过两次心跳后,对方被认为无法联系到
Pika的BlockingConnection的问题是,在进行某些API调用之前(例如,channel.basic\u publish()
,connection.sleep()
,等等),它无法响应心跳
到目前为止,我发现的方法是:
增加或停用超时
RabbitMQ在建立连接时与客户端协商超时。理论上,应该可以使用heartbeat_interval
参数用更大的值覆盖服务器默认值,但当前的Pika版本(0.10.0)使用服务器和客户端提供的值之间的最小值。这个问题是固定的电流
另一方面,通过将heartbeat\u interval
参数设置为0
,可以完全停用heartbeat功能,这可能会导致出现新问题(防火墙断开连接等)
重新连接
扩展@itsafire的答案,您可以编写自己的发布者类,以便在需要时重新连接。一个简单的实现示例:
import logging
import json
import pika
class Publisher:
EXCHANGE='my_exchange'
TYPE='topic'
ROUTING_KEY = 'some_routing_key'
def __init__(self, host, virtual_host, username, password):
self._params = pika.connection.ConnectionParameters(
host=host,
virtual_host=virtual_host,
credentials=pika.credentials.PlainCredentials(username, password))
self._conn = None
self._channel = None
def connect(self):
if not self._conn or self._conn.is_closed:
self._conn = pika.BlockingConnection(self._params)
self._channel = self._conn.channel()
self._channel.exchange_declare(exchange=self.EXCHANGE,
type=self.TYPE)
def _publish(self, msg):
self._channel.basic_publish(exchange=self.EXCHANGE,
routing_key=self.ROUTING_KEY,
body=json.dumps(msg).encode())
logging.debug('message sent: %s', msg)
def publish(self, msg):
"""Publish msg, reconnecting if necessary."""
try:
self._publish(msg)
except pika.exceptions.ConnectionClosed:
logging.debug('reconnecting to queue')
self.connect()
self._publish(msg)
def close(self):
if self._conn and self._conn.is_open:
logging.debug('closing queue connection')
self._conn.close()
其他可能性
我尚未探索的其他可能性:
- 将RabbitMQ连接和“发布”代码保留在后台线程上,该线程定期调用
,以响应服务器心跳connection.sleep()