Skip to main content
 首页 » 编程设计

python之RabbitMQ/Celery(事件): Server unexpectedly closed connection

2024年11月24日29cmt

大约 2-3 分钟后, celery 抛出以下回溯:

File "c:\program files (x86)\lib\site-packages\eventlet\hubs\selects.py", line 55, in wait 
    listeners.get(fileno, noop).cb(fileno) 
[2019-06-29 20:38:09,849: WARNING/MainProcess] File "c:\program files (x86)\lib\site-packages\celery\worker\pidbox.py", line 120, in loop 
    connection.drain_events(timeout=1.0) 
[2019-06-29 20:38:09,849: WARNING/MainProcess] File "c:\program files (x86)\lib\site-packages\kombu\connection.py", line 315, in drain_events 
    return self.transport.drain_events(self.connection, **kwargs) 
[2019-06-29 20:38:09,849: WARNING/MainProcess] File "c:\program files (x86)\lib\site-packages\kombu\transport\pyamqp.py", line 103, in drain_events 
    return connection.drain_events(**kwargs) 
[2019-06-29 20:38:09,849: WARNING/MainProcess] File "c:\program files (x86)\lib\site-packages\amqp\connection.py", line 500, in drain_events 
    while not self.blocking_read(timeout): 
[2019-06-29 20:38:09,849: WARNING/MainProcess] File "c:\program files (x86)\lib\site-packages\amqp\connection.py", line 505, in blocking_read 
    frame = self.transport.read_frame() 
[2019-06-29 20:38:09,849: WARNING/MainProcess] File "c:\program files (x86)\lib\site-packages\amqp\transport.py", line 252, in read_frame 
    frame_header = read(7, True) 
[2019-06-29 20:38:09,849: WARNING/MainProcess] File "c:\program files (x86)\lib\site-packages\amqp\transport.py", line 444, in _read 
[2019-06-29 20:38:09,849: WARNING/MainProcess] OSError: Server unexpectedly closed connection 
[2019-06-29 20:38:09,849: WARNING/MainProcess] Removing descriptor: 1044 

然而,当前任务的 worker 继续它的工作。但在我的 Web 应用程序中,我不断轮询 URL 以获取当前任务的更新。发生上述错误后,与 RabbitMQ 的连接似乎已关闭,因此应用程序无法再访问结果后端(也包括 RabbitMQ)。

我花了很多时间来弄清楚究竟是什么会引发该错误。我得出了一个非常模糊的结论,可能是因为 worker(目前使用的是:eventlet,因为在 Windows 上运行)无法向 RabbitMQ 发送心跳。 但是我完全糊涂了,因为有些人建议将 Heartbeat 值配置为 0(我这样做了,您可以在下面的配置中看到)。这也不能解决问题。

这是我当前的配置,它是 github 和 stackoverflow 上所有最佳建议的某种拼凑而成:

CELERY_BROKER_URL = 'pyamqp://' 
CELERY_RESULT_BACKEND = 'amqp://'                            
CELERY_BROKER_TRANSPORT_OPTIONS = {'confirm_publish': True}                  
CELERY_BROKER_HEARTBEAT = 0 
CELERY_BROKER_POOL_LIMIT = None 
CELERY_BROKER_TRANSPORT_OPTIONS = {'confirm_publish': True} 
CELERY_BROKER_CONNECTION_TIMEOUT = 20 
CELERY_BROKER_CONNECTION_RETRY = True 
CELERY_BROKER_CONNECTION_MAX_RETRIES = 100 
 
CELERY_TIMEZONE = 'UTC' 
CELERY_ENABLE_UTC = True 
CELERY_IGNORE_RESULT = False 
SQLALCHEMY_DATABASE_URI = userpass + basedir + dbname 
SQLALCHEMY_TRACK_MODIFICATIONS = False 

我希望 RabbitMQ 和 Celery 之间的连接稳定并且不会发生连接错误。

目前对我来说最大的问题是,我完全不知道错误究竟触发了什么。是worker没有给RabbitMQ发送心跳吗?是 RabbitMQ 本身吗?

我很高兴收到各种提示。

编辑: 忘了提,我还读到这与主机名有关。 我开始 celery :

celery -A tasks.celery worker --loglevel=info --pool=eventlet --without-mingle --without-gossip --without-heartbeat

它在本地主机上运行(网络服务器通过 XAMPP 运行)。 如果我检查 RabbitMQ 控制台,它不是“rabbit@localhost”而是“rabbit@DESKTOP-xxxx”。也许这会导致错误?

请您参考如下方法:

从所有 CELERY_BROKER 设置中删除 CELERY_ 前缀。为我工作。

这是我的 celeryconfig.py 中的一个片段:

BROKER_HEARTBEAT = 0
 
BROKER_POOL_LIMIT = None
 
BROKER_TRANSPORT_OPTIONS = {'confirm_publish': True}
 
BROKER_CONNECTION_TIMEOUT = 30
 
BROKER_CONNECTION_RETRY = True
 
BROKER_CONNECTION_MAX_RETRIES = 100
 
CELERY_RESULT_BACKEND = 'db+sqlite:///portal_tasks.db'
 
CELERY_TASK_TRACK_STARTED = True