部署至Elastic Beanstalk时SQS为何会出现celery队列?
核心原因说明
三个问题逐个说清楚:
- 自动出现的
celery队列生成逻辑
这是Celery内置的默认行为,和你的自定义配置没关系:只要worker启动、或者有没指定路由队列的任务发到Broker(不管是Redis还是RabbitMQ),框架会自动建一个名为celery的默认队列,用来兜底收没配路由的任务,还有传worker之间的控制消息,比如撤销任务、时钟同步、状态广播这类内部指令。 - 任务流程没跑崩的原因
这个自动生成的队列本来就不会干扰你配的自定义队列逻辑:- 要是你所有业务任务都显式配了路由到
default-dev或者broadcasts-dev,celery队列里只会跑极少的框架内部消息,不会有业务任务堆着,自然不影响正常跑 - 你写的两个worker启动逻辑本身是对的,正常绑定了自定义队列,业务任务的消费链路没出问题,所以整体流程看起来完全正常
- 要是你所有业务任务都显式配了路由到
- 跨队列消费的触发原因
你看到的“配了监听其他队列的worker去处理celery队列任务”,基本是两个常见坑导致的:- Celery默认开着
task_create_missing_queues=True,只要Broker上冒出来新队列(比如自动生成的celery队列),所有跑着的worker默认会自动绑上去,不会严格卡着启动时-Q参数指定的队列列表消费 - 跑在Elastic Beanstalk上的时候,如果systemd服务没配对停服逻辑,每次部署都会残留没带
-Q参数的旧Celery进程,这些残留进程默认就监听celery队列,很容易被当成新启动的worker跨队列消费
- Celery默认开着
配置调整方案
你贴的systemd配置大方向没问题,补几个调整就能彻底避开这类问题:
- 在Celery的应用配置里加下面几个参数,关掉自动建队,做严格的队列隔离:
# 禁止自动创建没在配置里显式声明的队列 task_create_missing_queues = False # 把框架默认队列改成你在用的default-dev,从根上不让它生成celery队列 task_default_queue = "default-dev" # 关掉worker远程控制,不再用默认队列传内部控制消息 worker_enable_remote_control = False
- 给两个systemd服务补上
ExecStop配置,避免EB部署的时候留僵尸进程,拿celery-default.service举例,Service段改成这样:
[Service] Type=simple Restart=always RestartSec=1 User=root EnvironmentFile=/opt/elasticbeanstalk/deployment/env WorkingDirectory=/var/app/current ExecStart=$PYTHONPATH/celery -A MyApp worker -Q default-dev -n default-worker \ --logfile=/var/log/celery/path-to-log --loglevel=DEBUG --concurrency=1 ExecStop=/bin/kill -s TERM $MAINPID KillMode=process TimeoutStopSec=60
- 改个笔误:你第二个服务的文件名写的是
celery-broadcats.service,和注释里的广播服务名对不上,后面查日志容易搞混,建议改成celery-broadcast.service。
内容的提问来源于stack exchange,提问作者Middledumbcat
相关产品推荐
相关产品推荐

