python使用celery实现异步任务

目录

一、使用celery

二、通用celery项目目录结构

三、相关文件代码

3.1、celery启动文件

3.2、celery配置文件

3.3、异步任务定义

3.4、异步任务调用

四、celery启动命令

五、其他


一、使用celery

celery需要中间件来做消息传递和结果存储,常用的消息中间件为:RabbitMQ、RocketMQ、Redis,其中redis最为方便,但没有web管理页面。

python 复制代码
pip install celery
pip install redis  # 使用 Redis 作为 broker/backend

二、通用celery项目目录结构

复制代码
project/                        # 项目root根路径
├── celery_app/                 # celery根目录
│   ├── tasks/                  # celery taks异步任务分模块
│   │   ├── module1/
│   │   │   ├── __init__.py
│   │   │   └── tasks.py
│   │   ├── module3/
│   │   │   ├── __init__.py
│   │   │   └── tasks.py
│   │   ├── module3/
│   │   │   ├── __init__.py
│   │   │   └── tasks.py
│   │   ├── __init__.py
│   ├── __init__.py             # celery启动文件(也可以写一个其他的py文件作为入口)
│   └── config.py               # celery配置文件

三、相关文件代码

3.1、celery启动文件

python 复制代码
# __init__.py
from celery import Celery
from celery_app.config import broker_url, result_backend

# 创建 Celery 实例
app = Celery(
    'myapp',
    broker=broker_url if broker_url else 'redis://localhost:6379/0',      # 消息代理
    backend=result_backend if result_backend else 'redis://localhost:6379/1',     # 结果后端
)

# 从配置文件加载配置(推荐)
app.config_from_object('config')

# 自动发现任务模块
app.autodiscover_tasks(['tasks'])

3.2、celery配置文件

python 复制代码
# config.py
from celery.schedules import crontab
    

# Broker 配置(使用redis的两个库作为celery的broker和backend)
broker_url = 'redis://localhost:6379/0'
result_backend = 'redis://localhost:6379/1'

# 序列化配置
task_serializer = 'json'
result_serializer = 'json'
accept_content = ['json']
timezone = 'Asia/Shanghai'
enable_utc = True

# 任务配置
task_track_started = True          # 跟踪任务开始状态
task_time_limit = 30 * 60          # 任务执行超时时间(秒)
broker_connection_retry_on_startup = True    # broker连接失败自动重试

# 结果配置
result_expires = 3600              # 结果过期时间(秒)
result_extended = True             # 存储更多结果信息

# 重试配置
task_acks_late = True              # 延迟确认任务
task_reject_on_worker_lost = True  # Worker 丢失时拒绝任务

# 并发配置(启动时也可指定)
worker_concurrency = 4             # Worker 并发数

# celery beat定时调度配置(需要启动celery_beat)
beat_schedule = {
    "test_beat_schedule": {
        "task": "celery_app.tasks.module1.tasks.celery_beat_schedule",
        "schedule": crontab(hour='10,11', minute=30),
    }
}

3.3、异步任务定义

python 复制代码
# module1.task.py
import requests

# 带重试配置的任务
@app.task(max_retries=5, default_retry_delay=60)
def request_api(url):
    try:
        response = requests.get(url, timeout=10)
        return response.json()
    except Exception as e:
        raise request_api.retry(exc=e)


# 普通异步任务
@app.task
def async_task():
    pass


# beat定时调度任务
@app.task()
def celery_beat_schedule():
    pass

3.4、异步任务调用

任务调用方面,celery提供了很多种调用方式(delay、apply_async、signature),用来处理简单的异步任务或任务链任务(B依赖A的结果这种),普遍的单个异步任务使用apply_async方法足够了。

python 复制代码
from celery_app import app
import time

# 执行异步任务获取结果

@app.task
def add(x, y):
    print(f"add 开始执行,线程: {time.strftime('%H:%M:%S')}")
    time.sleep(3)  # 模拟耗时操作
    result = x + y
    print(f"add 完成: {result}")
    return result

@app.task
def callback(result):
    print(f"callback 开始执行,线程: {time.strftime('%H:%M:%S')}")
    time.sleep(2)
    print(f"callback 完成,处理结果: {result}")
    return f"processed_{result}"

@app.task
def callback():
    print('callback回调函数执行出错时调用,若异常被捕获则不会走到这里')


if __name__ == '__main__':
    # 提交任务(带回调)
    async_result = add.apply_async(
        args=[4, 6], 
        link=callback.s(),
        link_error=callback_error.s()
    )
    async_task_id = async_result.id
    print(f"任务已提交,任务ID: {async_task_id }")
    print(f"主线程继续执行: {time.strftime('%H:%M:%S')}")

    # 使用 get()(阻塞主线程)
    result = add.delay(4, 6)
    value = result.get()  # ❌ 阻塞,等待 add 完成
    print("等待后才执行")  # 需要等待

四、celery启动命令

python 复制代码
# celery启动worker               并发数                队列                        日志级别                      后台运行      
celery -A celery_app worker --concurrency=4 --queues=high_priority,default --loglevel=info --detach --logfile=/var/log/celery.log

# celery beat调度启动
celery -A celery_app beat --loglevel=info

# 安全的停止celery
celery -A celery_app control shutdown


# 查看活跃任务
celery -A celery_app inspect active

# 查看注册的任务
celery -A celery_app inspect registered

# 查看 Worker 统计信息
celery -A celery_app inspect stats

# 查看队列长度
celery -A celery_app inspect active_queues

# 撤销任务
celery -A celery_app control revoke <task_id>

# 终止任务(强制)
celery -A celery_app control revoke <task_id> --terminate

五、其他

python 复制代码
# 常用命令
celery -A app worker -l info          # 启动 Worker
celery -A app beat -l info            # 启动 Beat
celery -A app flower                  # 启动监控
celery -A app purge                   # 清空所有消息
celery -A app inspect active          # 查看活跃任务
celery -A app control revoke <id>     # 撤销任务

# 常用装饰器
@app.task                              # 基础任务
@app.task(bind=True)                   # 绑定任务
@app.task(max_retries=3)               # 带重试
@app.task(rate_limit='10/m')           # 限流(每分钟10次)
@app.task(time_limit=30)               # 超时控制

# 常用调用
task.delay(*args, **kwargs)            # 简单调用
task.apply_async(args, countdown=10)   # 延迟调用
task.s(*args, **kwargs)                # 签名
相关推荐
Warson_L42 分钟前
Python `Annotated` 与 LangGraph Reducer 学习笔记
python
韩师傅44 分钟前
海天线算法的前世今生
python·计算机视觉
韩师傅1 小时前
当你的甲方设备过烂,要如何快速出效果?
python·计算机视觉
Warson_L1 小时前
LangGraph的MessageState and HumanMessage
python
韩师傅1 小时前
当你的甲方吐槽天空不够蓝,你应该如何应对
python·计算机视觉
Warson_L2 小时前
python的类&继承
python
Warson_L2 小时前
类型标注/type annotation
python
ThreeS4 小时前
手搓MiniVLA全实战教程-一步一步用pytorch解释原理与思路
人工智能·python
金銀銅鐵6 小时前
[Python] 模 n 乘法的逆元计算器
python·数学·游戏