Celery对接RabbitMQ自动创建3个队列的作用及相关问题咨询
Celery对接RabbitMQ自动创建队列问题解答
3个自动创建队列的作用
Celery以RabbitMQ为broker启动worker时,默认会创建3类队列,各自用途如下:
celery:默认持久化任务队列。调用task.delay()或未指定queue参数的apply_async()方法时,任务会默认投递到该队列;未通过-Q参数指定消费队列的worker,默认也会监听该队列拉取任务执行。这也是worker停止后唯一留存的队列。<worker名称>pidbox(对应你日志里的celery@ubuntu-s-1vcpu-1gb-blr1-01pidbox):远程控制指令专用临时队列。该队列是每个worker独占的,用于接收定向发给该worker的管理指令,比如查询运行中任务列表、动态调整消费队列、终止运行中任务、worker节点状态同步等操作,都是通过这类队列传递指令。celeryev.<随机标识>.<worker名称>:事件监控专用临时队列。worker运行时产生的全生命周期事件(任务接收、开始执行、执行成功/失败、worker心跳等)会投递到事件交换机,这类队列用于绑定接收对应事件,供celery events命令、Flower监控组件消费使用。
停止worker后部分队列自动删除的原因
两个自动消失的队列在创建时就被设置了非持久化、连接断开自动删除的属性:
durable: false:RabbitMQ重启后不会保留这类队列auto_delete: true:当队列的最后一个消费者(也就是对应启动的worker进程)断开与RabbitMQ的连接时,Broker会自动回收删除该队列
这是Celery的默认设计,属于正常行为,不存在配置错误,也不会丢失正常任务数据。
确认任务实际投递目标队列的方法
可以通过三种方式验证:
- 配置规则校验
如果没有自定义任务路由配置、调用任务时也没有手动指定queue参数,所有通过delay()发起的任务都会被投递到默认的celery队列。如果存在自定义路由,可以直接通过Celery路由API查询:
from myproject.celeryapp import app task_route = app.amqp.router.route_for_task("app1.tasks.add", args=(1,2), kwargs={}) print(f"任务实际投递队列:{task_route['queue'].name}")
- 运行状态校验
- worker启动时如果没有加
-Q参数指定消费队列,日志会输出[queues] celery字段,明确说明当前worker消费的是默认celery队列;你提供的日志中已经出现Task app1.tasks.add[xxx] received记录,说明worker已经从绑定的队列成功拉取到对应任务。 - 进入RabbitMQ管理后台的队列列表页,点开留存的
celery队列,通过「Get messages」功能拉取未消费的消息,消息体中的task字段会标注对应的任务名,和你发起的任务匹配即可确认投递位置。
- 临时关闭非必要队列验证
如果不需要远程控制、事件监控能力,可以在Celery配置中关闭对应功能,重启worker后就只会保留celery一个队列,此时所有任务的投递和消费都只会走该队列:
# 关闭远程控制功能,不再创建pidbox队列 app.conf.worker_enable_remote_control = False # 关闭任务事件上报,不再创建celeryev事件队列 app.conf.worker_send_task_events = False
内容的提问来源于stack exchange,提问作者Himanshu Poddar
相关产品推荐
相关产品推荐

