前言
1、环境配置
- python3.10
- celery5.0
- redis
2、推荐几篇遇到celery问题解决得好文章
- celery5.0开始使用小写得配置名
- Flask 使用 Celery 避免循环引用
- 解决报错(consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: timed out.)
代码部分
目录结构
applocation.py
用于创建flask工厂模式得文件
from datetime import datetime, date
from flask import Flask as _Flask
from flask.json import JSONEncoder as _JSONEncoder
from flask_cors import CORS
from config.base_config import BaseConfig
from app.base_module.base import db
class JSONEncoder(_JSONEncoder):
"""重写jsonify能序列化模型对象"""
def default(self, o):
if hasattr(o, 'keys') and hasattr(o, '__getitem__'):
return dict(o)
if isinstance(o, datetime):
return o.strftime('%Y-%m-%d %H:%M:%S')
if isinstance(o, date):
return o.strftime('%Y-%m-%d')
return JSONEncoder.default(self, o)
class Flask(_Flask):
json_encoder = JSONEncoder
flask_app = Flask(__name__)
# 跨域配置
CORS(flask_app, supports_credentials=True, origins="*")
flask_app.config.from_object(BaseConfig)
db.init_app(flask_app)
celery_app.py
用于创建celery对象
from celery import Celery
from application import flask_app
def make_celery(app):
my_celery = Celery(
app.import_name,
)
# celery.conf.update(app.config)
# 先加载配置文件,这里是config目录下的celeryconfig.py文件,传递参数时,不用带后缀名
my_celery.config_from_object("config.celeryconfig")
# 加载app的配置文件,这里有个坑,在flask配置文件里写的celery配置得用小写名
my_celery.conf.update(app.config)
# 将flask上下文对象加入celery,后续定义任务时,可以使用flask的orm模型
class ContextTask(my_celery.Task):
def __call__(self, *args, **kwargs):
with app.app_context():
return self.run(*args, **kwargs)
my_celery.Task = ContextTask
return my_celery
my_celery = make_celery(flask_app)
flask配置文件和celery配置文件
windows下启动celery
先安装:pip install eventlet
启动命令1:celery -A celery_app.my_celery worker -l info -P eventlet
启动命令2: celery -A celery_app.my_celery worker -l info -P solo
出现tasks为空的情况,可能为被加载任务,请在自己编写的视图当中导入自己的异步任务,celery加载时能扫描到,如果未扫描到的话,可以在celeryconfig中导入异步任务目录
出现以下图片即为启动成功
启动celery报循环导入错误解决
- 出现上面那种循环导入的问题,因为博主使用了蓝图,会出现循环引用的情况,暂时没想到更好的解决方案,所以单独放了出来,可以看最开始的有个
bule.py
文件 - 第二种解决方式,不在文件最开始的位置导入,在视图函数中导入,可以避免循环导入,类似下图