没有更多的任务要运行后,如何让芹菜死掉?

How can I make celery die after there are no more tasks to be run?

我有一个内存密集型 celery 任务,我希望它 运行 在大部分时间都处于关闭状态的昂贵 AWS 服务器中。

一个celery beat会每天调度一次任务,但也可以通过web应用程序(== django)手动调度。

调度任务就是向兔子队列发送消息。

然后我想使用 AWS api 发出命令来打开我昂贵的服务器,并让它启动工作人员, 等待他们在没有更多任务后死亡,然后关闭(并节省一些钱,因为服务器已关闭)。

我知道如何编写 AWS 脚本来开启我的服务器。问题是:我如何告诉芹菜 运行 任务直到队列为空 然后死 ?

是否有我可以提供的命令参数,或者我是否需要为此想出一些技巧?

我的建议:在您的任务完成后创建对 运行 的回调。此回调将使用 AWS 实例信息向您的 Web 应用程序发出请求,并使用此信息将其关闭。

编辑:这假设您将每个任务路由到一台新机器中。例如,在等待被销毁时,Celery worker 不应该接受任何新任务。

EDIT2:让这个昂贵的任务本身将请求发送到 Web 应用程序以销毁 Amazon 实例并杀死 Celery worker 也是一个好主意(检查 http://www.pythondoc.com/celery-3.1.11/userguide/workers.html#stopping-the-worker)/

Celery worker 就是一匹笨马。如果工作人员正在等待任务,则必须有其他东西监视工作人员并触发事件。

使用Flower to monitor your Celery cluster and their API消耗工人activity。

Flower 有一个带有 workers/tasks 数据的漂亮仪表板,信息就在那里,他们有一个 API。

感谢@iurisilvio 和@douglas-camata 的回答。我想我使用你们的一些想法找到了一个理想的解决方案:-)

我用这个 django 命令自己创建了一个简单的监视器(毕竟我的应用程序是 django)== wait_celery_idle.py

import time
from django.core.management.base import NoArgsCommand
from core.celery_utils import celery_count_status as ccount
import celery


class Command(NoArgsCommand):

    help = "Waits until celery is idle"

    def handle(self, *args, **options):
        while _count() > 0:
            time.sleep(5)


def _count():
    cinspect = celery.current_app.control.inspect()
    return ccount(cinspect.active()) + ccount(cinspect.scheduled()) + ccount(cinspect.reserved())

def ccount(d):
    k = d.keys()[0]
    return len(d[k])

然后我正常启动芹菜过程,如:./manage.py celery worker -c 1 --pidfile /tmp/celery.pid

然后我启动第二个进程(wait_and_die.sh)来监控celery,如果它闲置太久就会死掉。

#!/bin/bash
# wait_and_die.sh

./manage.py wait_celery_idle
kill $(cat /tmp/celery.pid)
sleep 10
sudo shutdown -h now

PS:这仅在我使用 rabbit 作为队列基础结构时有效 - cinspect.* 方法 return None 如果我使用 django 数据库作为队列(在 settings.py 中使用 CELERY_BROKER_URL='django://'