【发布时间】:2015-12-04 04:43:11
【问题描述】:
我正在编写一个脚本,它接收 HTTP 请求(使用 Tornado),解析它们,然后使用 pika 将它们发送到 RabbitMQ 代理。
代码如下:
def main():
conn_params = pika.ConnectionParameters(
host=BROKER_NAME,
port=BROKER_PORT,
ssl=True,
virtual_host=VIRTUAL_HOST,
credentials=pika.PlainCredentials(BROKER_USER, BROKER_PASS),
heartbeat_interval=HEARTBEAT_INTERVAL
)
conn = pika.BlockingConnection(conn_params)
channel = conn.channel()
# Create the web server which handles application requests.
application = tornado.web.Application([
(URL_BILLING, SomeHandler, dict(channel=channel))
])
# Start the server
application.listen(LISTENING_PORT)
tornado.ioloop.IOLoop.instance().start()
如您所见,我打开一个连接和通道,并将通道传递给创建的处理程序的任何实例,其想法是节省流量并避免为每个请求打开一个新的连接/通道。
我遇到的问题是连接在 3 次心跳 后关闭。我使用 Wireshark 来找出问题所在,但我只能看到服务器发送了一个 PSH(我假设这是心跳)并且我的脚本回复了一个 ACK。这发生了 3 次,它们之间有 HEARTBEAT_INTERVAL,然后服务器只发送一个 FIN,连接就终止了。
知道为什么会这样吗?另外,我应该保持连接打开还是为我需要发送的每条消息创建一个新连接更好?
感谢您的帮助。
更新:我查看了 RabbitMQ 日志,它说:
Missed heartbeats from client, timeout: 10s
我认为服务器是为了向客户端发送心跳,以确保它回答,这与我使用 Wireshark 观察到的一致,但从这个日志看来,它是客户端应该向服务器报告,而不是反过来,客户显然没有报告。我说对了吗?
更新:想通了,有点。阻塞连接(这是我使用的)无法发送心跳,因为它是阻塞的。正如this issue 中提到的,heartbeat_interval 参数仅用于与服务器协商连接,而客户端实际上并不发送心跳。既然如此,那么与 pika 保持长期联系的最佳方式是什么?即使我不指定heartbeat_interval,服务器默认每10分钟一次心跳,所以30分钟后连接就会死掉……
【问题讨论】: