芹菜中持久的长时间运行的任务
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编写 长时间运行的基于代码的工作流的 持久任务框架