目录机构
1、项目名称Demo,新建一个用于celery的包 celerytest,目录结构如上图
2、task_content1和task_content2是任务包,可以根据自己需要添加各种任务的包以便分类管理,里面的tasks.py是固定名称,会根据名称找任务
3、config.py是celery配置文件
注意目录的结构,结构,结构
# config.py
from kombu import Queue, Exchange
broker_url = 'redis://127.0.0.1:6379/1'
result_backend = 'redis://127.0.0.1:6379/2'
# 定义队列
task_queues = (
# 这个是默认的队列
Queue('default', exchange=Exchange('default'), routing_key='default'),
# 下面是自定义的
Queue('app_task1', exchange=Exchange('app_task1'), routing_key='app_task1'),
Queue('app_task2', exchange=Exchange('app_task2'), routing_key='app_task2'),
)
# 指定了`send_email load_email`这个方法由`app_task1`这个队列执行,`send_msg load_msg`由`app_task2`队列执行
task_routes = {
'celerytest.task_content1.tasks.send_email': {'queue': 'app_task1', 'routing_key': 'app_task1'},
'celerytest.task_content1.tasks.send_msg': {'queue': 'app_task2', 'routing_key': 'app_task2'},
'celerytest.task_content2.tasks.load_email': {'queue': 'app_task1', 'routing_key': 'app_task1'},
'celerytest.task_content2.tasks.load_msg': {'queue': 'app_task2', 'routing_key': 'app_task2'}
}
# task_content1.tasks.py
import time
from celerytest.main import app
@app.task
def send_email(email):
print('task_content1--start send email...')
time.sleep(3)
print('task_content1--send email end ...')
@app.task
def send_msg(msg):
print('task_content1--start send msg...')
time.sleep(2)
print('task_content1--send msg end ...')
@app.task
def send_default(default):
print('task_content1--start send default...')
time.sleep(5)
print('task_content1--send msg default ...')
# task_content2.tasks.py
import time
from celerytest.main import app
@app.task
def load_email(email):
print('task_content2--start load email...')
time.sleep(3)
print('task_content2--load email end ...')
@app.task
def load_msg(msg):
print('task_content2--start load msg...')
time.sleep(2)
print('task_content2--load msg end ...')
@app.task
def load_default(default):
print('task_content2--start load default...')
time.sleep(5)
print('task_content2--load msg default ...')
# main.py
from celery import Celery
import os
# 创建celery实例对象
app = Celery("diyname")
# 通过app对象加载配置
app.config_from_object("celerytest.config")
# 加载任务
# 参数必须必须是一个列表,里面的每一个任务都是任务的路径名称
# app.autodiscover_tasks(["任务1","任务2"])
app.autodiscover_tasks(["celerytest.task_content1", "celerytest.task_content2"])
from celerytest.task_content1.tasks import send_email, send_msg, send_default
from celerytest.task_content2.tasks import load_email, load_msg, load_default
result1 = send_email.delay("email-1")
print(result1.id)
result2 = send_msg.delay("msg-1")
print(result2.id)
# 如果task_routes里面配置了任务指定的queue,那么下面的就会走指定的queue
# result3 = send_default.delay('default-1')
# 如果task_routes里面没配置任务指定的queue,但又想走某个queue,可以通过 apply_async 动态指定queue
result3 = send_default.apply_async(args=('default-1',), queue='app_task1')
print(result3.id)
result4 = load_email.delay("email-2")
print(result4.id)
result5 = load_msg.delay("msg-2")
print(result5.id)
result6 = load_default.apply_async(args=('default-2',), queue='celery')
print(result6.id)
在启动worker时指定该worker执行哪一个queue中的任务。
(venv) D:\pycharm_workspace\Demo>celery -A celerytest.main worker -l info -P eventlet -c 3 -Q app_task1
(venv) D:\pycharm_workspace\Demo>celery -A celerytest.main worker -l info -P eventlet -c 3 -Q app_task2
(venv) D:\pycharm_workspace\Demo>celery -A celerytest.main worker -l info -P eventlet -c 3 -Q celery
如果没有加-Q参数,启动的worker会监听task_queues 中配置的所有队里中的任务
在同一台电脑,启动了多个worker时,报了一个错误: DuplicateNodenameWarning: Received multiple rep lies from node name: 解决方案:https://docs.celeryq.dev/en/latest/userguide/workers.html#starting-the-worker