【问题标题】:Tasks being repeated in Celery在 Celery 中重复的任务
【发布时间】:2016-09-28 15:30:44
【问题描述】:

几天后,我的 celery 服务将无限期地重复执行一项任务。这有点难以重现,但每周定期发生一次或更频繁,具体取决于正在处理的任务量。

我将不胜感激有关如何获取有关此问题的更多数据的任何提示,因为我不知道如何跟踪它。出现这种情况,重启 celery 会暂时解决。

我有一个 celery 节点和 4 名工人一起运行(版本 3.1.23)。代理和结果后端位于 Redis 上。我只发布到一个队列,我不使用 celery beat。

Django的setting.py中的配置是:

BROKER_URL = 'redis://localhost:6380'
CELERY_RESULT_BACKEND = 'redis://localhost:6380'

日志的相关部分:

[2016-05-28 10:37:21,957: INFO/MainProcess] Received task: painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647]
[2016-05-28 11:37:58,005: INFO/MainProcess] Received task: painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647]
[2016-05-28 13:37:59,147: INFO/MainProcess] Received task: painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647]
...
[2016-05-30 09:27:47,136: INFO/MainProcess] Task painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647] succeeded in 53.33468166703824s: None
[2016-05-30 09:43:08,317: INFO/MainProcess] Task painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647] succeeded in 466.0324719119817s: None
[2016-05-30 09:57:25,550: INFO/MainProcess] Task painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647] succeeded in 642.7634702899959s: None

任务由用户请求发送:

tasks.indicar_cliente.delay(indicacao_db.id)

这是source code of the taskcelery service configuration

为什么在服务运行一段时间后多次收到任务?如何获得一致的行为?

【问题讨论】:

  • 谁在调度任务?用户触发了吗? cron触发?你正在使用芹菜节拍。只发布到一个队列?粘贴你的 celery 配置
  • @MauroRocco 任务由用户请求发送(未安排,我不使用 celery beat)。我只发布到一个队列。我已经更新了我的问题以包含 celery 配置和任务源代码。
  • 嗨,你是说如果你在本地运行它并且只安排一个任务,你会看到 3 个任务正在执行?因为如果这是用户触发的,那么为每个请求它的用户安排一个任务是正常的。
  • @MauroRocco 任务通常会遵循所需的行为。然而,在服务运行几天后,任务被多次接收(在短时间内超过 100 次)。用户似乎没有触发任务,因为他们收到相同的任务 ID(如果用户正在请求新任务,日志将显示不同的 ID)
  • 你能贴出安排任务的代码吗?

标签: python celery celery-task


【解决方案1】:

它可能有点过时了,但我遇到了同样的问题并用 Redis 修复了它。长话短说,Celery 会等待一段时间来执行任务,如果时间已过,它会重新启动任务。这称为可见性超时。 文档的解释:

如果在可见性超时内未确认任务,则该任务 将被重新交付给另一个工人并执行。这引起 ETA/倒计时/重试任务的执行时间问题 超过可见性超时;事实上,如果发生这种情况,它将是 再次执行,并在循环中再次执行。所以你必须增加 可见性超时以匹配您最长的 ETA 时间 打算使用。请注意,Celery 将在 worker 处重新传递消息 关闭,因此具有较长的可见性超时只会延迟 在电源故障的情况下重新交付“丢失”的任务或 强行解雇工人。

选项示例: https://docs.celeryproject.org/en/stable/userguide/configuration.html#broker-transport-options

详情: https://docs.celeryproject.org/en/stable/getting-started/brokers/redis.html#visibility-timeout

【讨论】:

  • 只是补充一下,使用“acks_late”可能会有一些有趣的相互作用。基本上,如果您将其设置为 true,则任务只会在完成时确认。这意味着运行时间较长的任务可能会导致此问题。顺便谢谢你在这里的回答。超级有帮助。
【解决方案2】:

使用rabbitmq broker代替redis解决。

【讨论】:

    【解决方案3】:

    我遇到了这样的问题。提高芹菜 visibility timeout 不起作用。

    事实证明,我还运行了一个 Prometheus 导出器,它实例化了它自己的 Celery 对象,该对象使用默认的可见性超时——因此取消了我在应用程序中设置的更高超时。

    如果您有多个 Celery 客户端——无论它们是用于提交任务、处理任务还是只是观察任务——确保它们都具有完全相同的配置。

    【讨论】:

      猜你喜欢
      • 2019-02-16
      • 2011-07-17
      • 2012-09-21
      • 2011-06-19
      • 2012-04-12
      • 2011-07-05
      • 1970-01-01
      • 1970-01-01
      • 2017-05-09
      相关资源
      最近更新 更多