【问题标题】:Long running Celery tasks result in ConnectionResetError: [Errno 104] Connection reset by peer长时间运行的 Celery 任务导致 ConnectionResetError: [Errno 104] Connection reset by peer
【发布时间】:2022-08-16 18:49:20
【问题描述】:

在我的 Django 应用程序中,我使用 Celery 来处理运行时间很长的任务。其中一项任务必须在最后将记录写入数据库,以确认该过程已完成。出于某种原因,如果任务运行了这么长时间(这里说 4 小时或更长时间) 我得到了这个:

ConnectionResetError:[Errno 104] 对等方重置连接

一旦我在任务的最后触发对数据库的写操作,就会发生这种情况,例如:

 Files.objects.filter(pk=files_obj).update
 ... etc

知道为什么对等方重置连接(在我的例子中是 MariaDB)会很有趣。 Django 不使用连接池为我管理数据库连接吗? 我还在 Django 端检查了我的 Redis 配置,在我看来只有以下几行才是真正重要的:

BROKER_TRANSPORT_OPTIONS = {\'visibility_timeout\': 86400}  # 24 hrs.
CELERYD_TASK_TIME_LIMIT = 86400  # 24 Hrs.
CELERYD_TASK_SOFT_TIME_LIMIT = 86400  # 24 Hrs.

有没有办法让函数触发一个新的连接?对我来说,只要任务正在运行,Celery 任务似乎就会使 SQL 连接保持活动状态。但是数据库后端不尊重这一点这么久。

这就是我开始我的芹菜工人的方式:

celery -A App worker --pool=gevent --concurrency=4 --loglevel INFO --pidfile= --schedule=/home/$OS_USER/celery-schedule

提前致谢。

  • 你设法解决了这个问题吗?我有同样的问题。
  • @Olney1 请看我的回答

标签: django mariadb


【解决方案1】:

找到了解决办法,抱歉回复晚了。基本上,Django 使用连接池管理 SQL 连接。默认情况下它会为您执行此操作。这很好,但在我的情况下,它导致了与数据库的池连接失效的问题,导致“对等连接重置”错误。

要解决此问题,您只需调用以下命令:

close_old_connections()

通常,任务的运行可能类似于以下步骤:

  1. 获取处理实际任务所需的所有信息,例如从数据库中获取文件对象等。
  2. 处理数据(例如转换视频)可能需要数小时。
  3. 在视频转换后更新数据库中的内容。

    在第 3 阶段,您很可能会因为数据库连接中断而失败。因此,在视频转换完成后,您想要更新数据库中的内容,只需关闭所有旧数据库连接,如下所示:

    ...
    close_old_connections()
    try:
       Files.objects.filter(pk=files_obj).update(
           sprites_path=cover_placement_path,
       )
    ...
    

    您也可以说 close_old_connections() 通常是一个好习惯 如果您可以预期一个动作运行的时间更长,而所有事情都发生在一个单一的函数中,比如 celery 任务。

    干杯。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    • 2020-01-15
    • 2019-04-30
    • 2018-07-28
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多