我目前正致力于将现有的基于Django服务器的单个服务器移植到Amazon Elastic Beanstalk。到目前为止,我已成功设置项目以使用RDS,弹性搜索,简单电子邮件服务和S3而不会有太多麻烦。我正在使用Code Deploy为Django项目构建Docker容器并部署到Elastic Beanstalk环境。所有这些都很漂亮,但我遇到了一个问题,试图让Elastic Beanstalk工作环境与这个设置配合良好。
我正在将相同的Docker容器部署到我的工作环境,但使用不同的起点来运行celery -A project worker -l INFO
而不是gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app --workers 3
。这似乎有效;工作人员消耗消息并处理它们就好了,但它经常看起来一次停止工作几分钟,即使队列中有等待的消息积压。
在我的测试期间,我正在尝试运行我的发票生成例程,通过在group
中使用Celery chain
为每个帐户的发票排队消息,以便它处理发票,然后通过电子邮件向我发送“完成”通知。总的来说,我在一开始就在队列中有大约250条消息。尾随芹菜日志寻找Docker容器,我可以看到8-12个消息之间的任意组被拾取,然后在一两秒内处理,但随后工人一次闲置几分钟。通常大约4分钟。
我没有看到任何我能想到的任何错误。
我还试验了扩展工作者环境,以便它运行多个工作节点,但这只是将问题分散到多个节点。也就是说,不是一个工人拿起8-12个消息,而是两个工人在4-6个消息之间拾取,处理它们,然后闲置。
在这一点上,我不知道我应该再看什么了,我正在考虑完全放弃工人环境。也许在与Web服务器相同的环境中运行Celery工作进程更有意义?我不想这样做,因为我认为为Web服务器和工作人员独立设置扩展规则要容易得多,但它开始看起来我没有其他选择。
在这种设置中是否存在我缺少的东西或Celery工作环境以这种方式表现的某些原因?
鉴于改变芹菜工人或节点的数量并没有改变延迟,这让我相信问题在于某个芹菜工人如何试图从SQS队列中拉出任务。
暂停4分钟,它似乎非常接近default retry delay present in Celery's Task.default_retry_delay
,这是3分钟。它也可能与Task.rate_limit
,the config parameter有关,它将限制芹菜工人在给定时间内接受的任务总数。
作为第一步,我将进入你的芹菜配置文件并手动更改这两个值 - 使它们更高,看看它如何影响超时或更改应用程序吞吐量。