没有更多的任务要运行后,如何让芹菜死掉?
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://'
)
我有一个内存密集型 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://'
)