我在 Heroku 上使用 Django 和 celery 以及 Redis。 我有两个队列,称为“celery”和“letters”
我在 Heroku 上有两种工作类型
我的heroku procfile如下所示:
worker: REMAP_SIGTERM=SIGQUIT celery -A shareforce.taskapp worker --loglevel=info --concurrency=3 --prefetch-multiplier=2 -Q letters,celery
letter-worker: REMAP_SIGTERM=SIGQUIT celery -A shareforce.taskapp worker --loglevel=info --concurrency=2 --prefetch-multiplier=2 -Q letters -X celery
在我的配置中我有这个设置
CELERY_TASK_DEFAULT_QUEUE = "celery"
我有以下芹菜任务:
@shared_task(queue="celery")
def generate_export(**kwargs):
pass
我这样称呼它:
generate_export.delay()
偶尔,大约有五十分之一的人会在信件工作人员上运行,导致其内存不足,从而重新启动应用程序,从而杀死任一工作人员上正在运行的任何任务。
我不知道这怎么可能或如何解决。
任何有关如何修复或调试它的建议的帮助将不胜感激。
您遇到的问题可能是由任务路由设置错误或 -X celery 标志未能正确从 letter-worker 中删除 celery 队列引起的。
这里更全面地解释了此问题的潜在原因和解决方案。
验证任务队列中的分配:验证generate_export是否正确赋予了queue =“celery”。鉴于您说它偶尔在信件工作人员上运行,Celery 的路由中可能存在竞争条件或错误。
Celery 的排除 (-X) 标志 您的 letter-worker 配置的 -X celery 设置旨在将 celery 队列排除在外。但有时,由于配置错误,信件工作人员可能会无意中从 celery 队列中选择作业。
解决方案:确保在您的配置中配置了正确的路由规则,并将作业手动路由到适当的工作人员,而不是使用 -X celery。
将以下内容添加到您的settings.py中:
通过这种方式,作业将始终按照您指定的路由规则发送到正确的队列。
对您的 Heroku Procfile 进行以下更改: 通过这种方式,worker 仅处理来自 celery 队列的作业,并且 letter-worker 仅处理来自 letters 队列的任务。由于队列分配负责分离,因此不再需要 -X 标志。
管理工作队列中的并发 限制并发可以通过减少在信件工作人员上执行的并发任务量来帮助您防止信件工作人员遇到内存过载。尽管您将并发度设置为 2,但如果内存问题持续存在,您可能希望进一步减少并发度,以防止较小的作业使较小的实例过载。
额外故障排除 检查工作日志记录:在 Celery 中打开更彻底的日志记录,以监控哪些员工正在从事哪些工作。这将帮助您确定为什么将特定任务分配给不正确的员工。 通过使用worker命令将日志级别设置为debug,您可以提高日志的详细程度: 注意 Redis:Redis 的队列中有时可能仍有某些作业,由于旧的设置或任务分配冲突,这些作业被不正确的工作线程拾取。可以监视 Redis 队列以确保它们正常运行。
完整设置:修改 Procfile 以在芹菜队列和信件队列之间划分劳动力。 确保您的设置清楚地说明了任务路由。py。 修改内存密集型或并发密集型进程以避免较小实例过载。 要密切关注任务执行和路由,请使用调试和日志记录。 按照这些说明,您应该能够保证您的信件工作人员仅完成信件队列中的作业,而远离芹菜中的任务。