芹菜中持久的长时间运行的任务

Posted

技术标签:

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

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

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

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

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

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

感谢您的帮助!

【问题讨论】:

【参考方案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).',) 这还不算太糟糕,实际上,因为它仍在队列中。不是我只需要另一个工人来接它。

以上是关于芹菜中持久的长时间运行的任务的主要内容,如果未能解决你的问题,请参考以下文章

为什么芹菜会给rabbitmq添加数千个队列,这些队列在任务完成后似乎会持续很长时间?

使用c#的 async/await编写 长时间运行的基于代码的工作流的 持久任务框架

在 dask 或 Dramatiq 中带有 (bind=True) 的芹菜?

芹菜任务结果不与 rpc 保持一致

气流将长时间运行的任务标记为失败

带有异步或长时间运行任务的 UndoManager