如何永久删除RabbitMQ中的celery任务?
我现在的celery设置上大约有10,000个定时任务。最开始我并不知道什么是定时任务,就决定提前几个月安排发送跟进邮件。
回想起来,安排超过1小时以后的任务可能不是个好主意,因为每次重启工作进程时,它都需要从rabbitMQ重新接收所有的定时任务,然后这些任务就会一直在内存里待着。
我的问题是,如果我需要撤销一个任务,它并不会直接删除。任务会留在内存中,但撤销队列里会包含这个任务的ID。当这个任务准备执行时,celery会检查它是否被撤销,如果是的话,就会在这个时候撤销它。
不过,任务在此之前仍然会留在内存里,如果我在任何时候重启我的工作进程,撤销队列会被清空,因为我没有让它持久化。
我该如何永久性地从我的celery工作进程中移除一个任务?我基本上只需要向rabbitMQ发送一个确认,这样rabbit就能彻底删除它,并且如果我重启celery,它就不会再出现了。
我查看了文档和源代码,也尝试在命令行中自己操作,但我就是找不到合适的地方来确认任务给rabbitMQ,然后让它永远消失。
2 个回答
1. 要彻底清空等待任务的队列,你必须先停止所有的工作进程(http://celery.readthedocs.io/en/latest/faq.html#i-ve-purged-messages-but-there-are-still-messages-left-in-the-queue):
$ sudo rabbitmqctl stop
或者(如果RabbitMQ/消息代理是由Supervisor管理的):
$ sudo supervisorctl stop all
2. 然后从特定的队列中清空任务:
$ cd <source_dir>
$ celery amqp queue.purge <queue name>
3. 启动RabbitMQ:
$ sudo rabbitmqctl start
或者(如果RabbitMQ是由Supervisor管理的):
$ sudo supervisorctl start all
如果你只使用了一个队列或一个任务,这个操作很简单:
根据文档:
答案是:你可以使用celery purge命令来清空所有配置的任务队列:
$ celery -A proj purge
或者通过编程的方式:
>>> from proj.celery import app
>>> app.control.purge()
1753
如果你只想清空特定队列中的消息,你需要使用AMQP API或者celery amqp工具:
$ celery -A proj amqp queue.purge <queue name>
数字1753表示被删除的消息数量。
你还可以在启动工作进程时加上--purge
参数,这样在工作进程启动时就会清空消息。
更新: 如果你有多个队列或任务
我不知道有没有办法在RabbitMQ中编辑它们,因为服务器并不是为了那样访问/编辑/删除排队的任务而设计的,但你可以在代码中禁用你的任务:
@task
def my_old_task()
pass
这样所有的任务都会按计划运行,但不会执行任何操作;因为它们既没有被重命名也没有被删除,所以你不会遇到任何错误。
显然,你应该更新你的代码来停止调度这些任务。过一段时间后,这种类型的任务就不会再被调度了,这时你可以删除相关的代码。