当前位置: 首页 > 知识库问答 >
问题:

Pika SelectConnection适配器的close()方法不关闭连接

幸乐湛
2023-03-14

我有一个简单的AMQP / RabbitMQ异步消费者,使用Pika库用Python编写,并基于Pika文档中的异步消费者示例。主要区别在于我想在线程中运行我的线程,我希望它正确关闭连接,然后在一定时间间隔后退出(即终止线程)。以下是我打开连接并设置超时的方法。我还打开一个频道,创建一个交易所并绑定一个队列......一切正常。

def connect(self):
  LOGGER.info('OPEN connection...')
  return pika.SelectConnection(self._parameters, self.on_connection_open, stop_ioloop_on_close=False)

def on_connection_open(self, unused_connection):
  LOGGER.info('Connection opened')
  self.add_on_connection_close_callback()
  self._connection.add_timeout(5, self.timer_tick)
  self.open_recv_channel()

下面是超时回调:

def timer_tick(self):
  LOGGER.info('---TICK---')
  self._stop()

这是_stop方法:

def _stop(self):
  LOGGER.info('Stopping...')
  self._connection.close()
  LOGGER.info('Stopped')
  time.sleep(5)
  self._connection.ioloop.stop()

下面是启动线程的run方法:

def run(self):
  print "-Run Started-"
  self._connection = self.connect()
  self._connection.ioloop.start()
  print "-Run Finished-"

以下是main()的主要部分:

client = TestClient()
client.start()
client.join()
LOGGER.info('Returned.')
time.sleep(30)

我的问题是“self._connection.close()”无法正常工作。我添加了一个on_close回调:

self._connection.add_on_close_callback(self.on_connection_closed)

但是on_connection_closed()从来没有被调用过。此外,连接没有关闭。我可以在RabbitMQ管理Web界面中看到它,即使线程完成,它仍然存在。这是输出:

-Run Started-
2015-01-28 14:39:28,431: OPEN connection...
2015-01-28 14:39:28,491: Queue bound
(...[snipped] various other messages here...)
2015-01-28 14:39:28,491: Issuing consumer related RPC commands
2015-01-28 14:39:28,491: Adding consumer cancellation callback
(Pause here waiting for timeout callback)
2015-01-28 14:39:33,505: ---TICK---
2015-01-28 14:39:33,505: Stopping...
2015-01-28 14:39:33,505: Closing connection (200): Normal shutdown
2015-01-28 14:39:33,505: Stopped
-Run Finished-
2015-01-28 14:39:39,507: Returned.

“Closing connection(200):Normal shutdown”来自Pika,但我的on_close或on_cancel回调都没有被调用,无论我是从关闭通道开始,还是只是关闭连接。唯一有效的是使用“basic_cancel”停止消费者,这会导致调用我的“on_cancel_callback”。

我想在主程序中使用一个循环来创建和销毁消费者线程,但是现在,每次我运行一个循环,我都会留下一个孤立的连接,所以我的连接数量会无限增加。当程序关闭时,连接确实会消失。

使用connection.close()应该有效:来自Pika文档:

关闭(reply_code=200, reply_text='正常关机')

断开与 RabbitMQ 的连接。如果有任何打开的通道,它将在完全断开连接之前尝试关闭它们。具有活跃使用者的通道将尝试向 RabbitMQ 发送 Basic.Cancel,以便在关闭通道之前完全停止消息传递。

共有1个答案

贾俊艾
2023-03-14

如果你在线程之间共享连接,这可能会导致问题。< code>pika不是线程安全的,连接不应由不同的线程使用。

常见问题解答的第一部分:

问题:

鼠兔线安全吗?

一个:

Pika在代码中没有任何线程的概念。如果您想将Pika与线程一起使用,请确保在该线程中为每个线程创建了一个Pika连接。跨线程共享一个Pika连接是不安全的。

 类似资料:
  • 《 C++ open打开文件》一节中,详细介绍了文件流对象如何调用 open() 成员方法打开指定文件。相对应地,文件流对象还可以主动关闭先前打开的文件,即调用 close() 成员方法。 我们知道,调用 open() 方法打开文件,是文件流对象和文件之间建立关联的过程。那么,调用 close() 方法关闭已打开的文件,就可以理解为是切断文件流对象和文件之间的关联。注意,close() 方法的功能

  • 我的连接器类: 连接器。JAVA 这是我的DAO类(简化):UserDAO. java 在这里,我发现了关于Hikari的一些事实的问题: 您必须在HikariCP为您提供的连接实例上调用关闭() 可能是我的不起作用,因为它只是Hikari在方法中提供给我的连接的副本。

  • 本文向大家介绍Python Selenium 之关闭窗口close与quit的方法,包括了Python Selenium 之关闭窗口close与quit的方法的使用技巧和注意事项,需要的朋友参考一下 selenium关闭窗口有两个方法,close与quit,我们稍作研究便知道这两个方法的区别。 1.看源码或API 这是close()的说明: 这是quit()的说明: 从这里就很明显的看出来这两个方

  • 问题内容: 我试图关闭数据库连接,但是有点困惑 我是否必须靠近它 要么 两者之间有什么区别? 问题答案: 这些方法只能关闭。您仍然必须关闭全部和实例。我建议这样做。就像是, 如果您使用我的实用程序,则finally块可能是,

  • 为何关闭项目? eclipse工作区可以包含任意数量的项目。 项目可以处于打开状态或关闭状态。 开放项目 - 消耗记忆。 占用构建时间,尤其是在使用“ Start a build immediately选项清除所有项目(项目→清除所有项目)时。 如何关闭项目? 如果项目未处于活动开发阶段,则可以将其关闭。 要关闭项目,请从“项目”中选择“关闭项目”菜单项。 在Package Explorer中关闭

  • 我认为这是一个非常简单的问题,但在过去的几个月里,我遇到了很多次。我在一个方法中创建一个扫描器,然后尝试关闭它,它总是给我一个错误。这一次的错误是: 错误:无法从静态上下文扫描程序引用非静态方法close()。close();