为什么不直接使用 Celery/RQ/Huey/TaskTiger?
不幸的是,WakaTime 使用 Celery 已经快 10 年了。在那段时间里,我经历了许多严重的错误,其中一些在被引入多年后仍然存在。Celery 曾经相当不错,但功能膨胀使项目难以维护。同样在我看来,将代码分成三个独立的 GitHub 存储库会使代码库难以阅读。
然而,主要原因是: Celery 延迟任务无法扩展。
如果您使用 Celery 延迟任务,随着您的网站最终增长,您将开始看到此错误消息:
QoS: Disabled: prefetch_count exceeds 65535
当这种情况发生时,工作人员会停止处理所有任务,而不仅仅是延迟的任务!随着 WakaTime 的增长,我们开始更频繁地遇到这个错误。
我尝试了RQ、Huey和TaskTiger,但它们缺少功能并且处理任务比 Celery 慢。对于像 WakaTime 这样的网站来说,分布式任务队列是必不可少的,我已经厌倦了遇到 bug。出于这个原因,我决定尽可能构建最简单的分布式任务队列,同时仍然提供 WakaTime 所需的所有功能。
介绍 WakaQ
WakaQ是一个新的 Python 分布式任务队列。使用它在后台运行代码,使您的网站保持快速和快速,并让您的用户保持快乐。
WakaQ 很简单
它只有 1,264 行代码!
$ find . -name '*.py' -not -path "./migrations*" -not -path "./venv*" | xargs wc -l | grep " total" | awk '{print $1}' | numfmt --grouping
1,264
从第一行代码到在 WakaTime 完全取代 Celery只用了一周时间。这说明了它的简单性。
每个队列都是使用Redis 列表实现的。延迟任务使用Redis 排序集实现自己的队列。广播任务共享一个Redis Pub/Sub queue。
WakaQ 具备所有必要的功能
- 队列优先级
- 延迟任务(在 timedelta eta 之后运行任务)
- 计划的 cron 定期任务
- 广播任务(在所有工作人员上运行任务)
- 任务软硬超时限制_
- 可选择在软超时时重试任务
- 通过在达到max_mem_percent时重新启动工作程序来防止内存泄漏
- 超级最小且可维护
超出范围的功能包括速率限制、排他锁定、存储任务结果和任务链接。这些很容易添加到您的应用程序的任务代码中,并且您可能无论如何都希望根据您的应用程序的需求来实现这些。
WakaQ 可以使用了
WakaQ是稳定的,可以在生产中使用。WakaQ 目前为WakaTime网站的 prod 中的所有后台任务提供支持,包括但不限于:
- 发送代码统计电子邮件报告
- 更新我们的 LetsEncrypt SSL 证书
- 预缓存仪表板、回购徽章和可嵌入图表
- 我们不想阻止网络请求的其他任何事情
它是在BSD 许可下发布的,因此您可以在开源和闭源项目中使用它。如果您发现任何错误,请打开一个问题,但在请求新功能之前请三思而后行 。
原文标题:Building a Distributed Task Queue in Python
原文作者: Alan Hamlett
原文链接:https://wakatime.com/blog/56-building-a-distributed-task-queue-in-python