【问题标题】:Persistent Long Running Tasks in Celery芹菜中持久的长时间运行的任务
【发布时间】:2015-11-16 20:47:01
【问题描述】:

我正在开发一个基于 Python 的系统,以便将长时间运行的任务排入队列。

任务源自生成“令牌”的外部服务,但是一旦基于该令牌创建它们,它们应该连续运行,并且只有在被代码明确删除时才会停止。
该任务启动一个 WebSocket 并在其上循环。如果套接字关闭,它会重新打开它。基本上,任务不应该得出结论。

我构建此解决方案的目标是:

  1. 在正常重启工作器时(例如加载新代码),任务应重新添加到队列中,并由某个工作器拾取。
  2. 发生不正常关机时也会发生同样的情况。
  3. 2 个工人不应该在同一个令牌上工作。
  4. 其他进程可能会创建更多任务,这些任务应定向到处理特定令牌的同一工作人员。这将通过将这些任务发送到以令牌命名的队列来解决,工作人员应该在启动令牌的任务后开始收听该队列。我列出这个要求是为了解释为什么这里甚至需要任务引擎。
  5. 独立服务器、快速代码重新加载等 - 每个任务的停机时间最短。

我们所有的服务器端都是 Python,看起来 Celery 是它的最佳平台。 我们在这里使用了正确的技术吗?我们应该考虑其他任何架构选择吗?

感谢您的帮助!

【问题讨论】:

    标签: python rabbitmq task celery long-running-processes


    【解决方案1】:

    根据docs

    当启动关闭时,worker 将在它实际终止之前完成所有当前正在执行的任务,因此如果这些任务很重要,您应该等待它完成,然后再执行任何激烈的操作(例如发送 KILL 信号)。

    如果工作人员在经过考虑的时间后不会关闭,例如由于任务陷入无限循环,您可以使用 KILL 信号强制终止工作人员,但请注意当前正在执行的任务将丢失(除非这些任务设置了 acks_late 选项)。

    使用retry or acks_late,你可能会得到你想要的东西

    总体而言,我认为您需要实现一些额外的应用程序端作业控制,也许还需要一个锁定服务。

    但是,是的,总的来说,你可以用芹菜做到这一点。是否有更好的技术……这超出了本网站的范围。

    【讨论】:

    • 我在“process_token”任务中使用acks_late=True, track_started=True。而且我将在应用程序级别采取保护措施,以确保不会有 2 个任务在同一个令牌上。
    • 使用 acks_late 和 track_started,我已经到了 process_token 任务达到“失败”状态的地步,原因是 WorkerLostError('Worker exited prematurely: signal 15 (SIGTERM).',) 这还不算太糟糕,实际上,因为它仍在队列中。不是我只需要另一个工人来接它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 2019-02-26
    • 2015-05-11
    • 2017-05-24
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多