news 2026/6/23 19:07:00

【RealEarthStudio】使用Celery+Redis执行异步任务

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【RealEarthStudio】使用Celery+Redis执行异步任务

使用 Celery + Redis 执行异步任务

  • 引言
  • 一、主要功能
  • 二、实现步骤
    • 2.1 安装依赖
    • 2.2 配置 Celery
    • 2.3 在 settings.py 中配置 Celery
    • 2.4 定义异步任务(tasks.py)
    • 2.5 在 View 中触发任务
    • 2.6 错误修正

引言

计算机专业硕士在读,主要研究方向是特定目标大斜视角目标检测与定位。因为要做的是特定目标,公开数据集较少,经过多方考虑还是决定要自建数据集。最终考虑的解决方案还是Blender+Python API的方式,项目起名叫RealEarthStudio
这系列文章主要对开发过程进行记录,方便我个人后续查看,也给相类似方向的同学提供一个思路。

【项目目录】:项目目录链接


一、主要功能

  • 功能:使用 Celery + Redis 执行异步任务。
  • 背景:上一篇文章已经安装了Redis数据库,现在配置Celery将耗时任务交给后台工作进程处理。
  • 效果
  • 码云项目链接:https://gitee.com/charlsewyq/RealEarthStudio

二、实现步骤

2.1 安装依赖

在命令行中运行:

pipinstallcelery redis django-celery-results

2.2 配置 Celery

  • 在项目根目录(与settings.py同级)创建celery.py
importosfromceleryimportCelery# 设置 Django 的默认设置模块os.environ.setdefault('DJANGO_SETTINGS_MODULE','RealEarthStudio.settings')app=Celery('RealEarthStudio')# 从 Django settings 中加载配置,以 CELERY_ 开头的项app.config_from_object('django.conf:settings',namespace='CELERY')# 自动发现各 app 下的 tasks.pyapp.autodiscover_tasks()
  • 修改__init__.py(确保 Celery 应用被加载):
from.celeryimportappascelery_app __all__=('celery_app',)

2.3 在 settings.py 中配置 Celery

# Celery 配置CELERY_BROKER_URL='redis://127.0.0.1:6379/0'# 使用 Redis 作为消息代理CELERY_RESULT_BACKEND='django-db'# 将任务结果存入数据库(需安装 django-celery-results)CELERY_ACCEPT_CONTENT=['json']CELERY_TASK_SERIALIZER='json'CELERY_RESULT_SERIALIZER='json'CELERY_TIMEZONE='Asia/Shanghai'# 如果使用 django-celery-results,添加到 INSTALLED_APPSINSTALLED_APPS+=['django_celery_results',]

2.4 定义异步任务(tasks.py)

app中新建tasks.py文件:

fromceleryimportshared_taskimportosfromdjango.utilsimporttimezonefrom.modelsimportRenderingTask@shared_taskdefexecute_render_task(render_id):""" 异步执行渲染任务 """try:render_task=RenderingTask.objects.get(render_id=render_id)# 写入信息文件full_filepath=os.path.join(render_task.rendered_result_dir.path,"info.txt")withopen(full_filepath,'w',encoding='utf-8')asf:f.write(f"=== 渲染任务信息 ===\n")f.write(f"渲染任务ID:{render_task.render_id}\n")f.write(f"渲染时间:{render_task.render_time.astimezone(timezone.get_default_timezone())}\n")f.write(f"渲染器类型:{render_task.renderer_type}\n")f.write(f"图像分辨率:{render_task.image_width}×{render_task.image_height}\n")f.write(f"总像素数:{render_task.image_pixels}\n\n")f.write(f"=== 模型信息 ===\n")f.write(f"目标模型数量:{render_task.target_models.count()}\n")ifrender_task.target_models.exists():fori,target_modelinenumerate(render_task.target_models.all(),1):all_categories=set(target_model.category.all())forcatinlist(all_categories):parent=cat.parentwhileparent:all_categories.add(parent)parent=parent.parent category_names=", ".join([str(cat.name)forcatinall_categories])f.write(f" 目标模型{i}:{target_model.model_id}({category_names})\n")f.write(f"场景模型数量:{render_task.scene_models.count()}\n")ifrender_task.scene_models.exists():fori,scene_modelinenumerate(render_task.scene_models.all(),1):category_names=", ".join([str(cat.name)forcatinscene_model.category.all()])f.write(f" 场景模型{i}:{scene_model.model_id}({category_names})\n")f.write(f"\n=== 光照参数 ===\n")f.write(f"日光方位角:{render_task.sun_azimuth}°\n")f.write(f"日光高低角:{render_task.sun_elevation}°\n\n")f.write(f"=== 相机参数 ===\n")f.write(f"相机距离列表:{render_task.camera_distances}\n")f.write(f"相机高低角列表:{render_task.camera_elevations}\n")f.write(f"相机方位角间隔:{render_task.camera_rotation_step}°\n\n")returnf"渲染任务{render_id}完成"exceptExceptionase:# 处理错误情况returnf"渲染任务{render_id}失败:{str(e)}"

2.5 在 View 中触发任务

app中修改views.py文件:

fromrest_framework.viewsimportAPIViewfrom.tasksimportexecute_render_taskfromutils.statusimportresponseasmy_responseclassStartRender(APIView):@staticmethoddefget(request,render_id):# 开始渲染print('准备启动渲染任务')execute_render_task.delay(render_id)print('渲染任务启动完成')# 返回信息data={"render_id":render_id,# "render_time": render_task.render_time,}returnmy_response.success(data=data,message="开始渲染")

2.6 错误修正

我在做的时候出现一个问题。查看Celery日志:

celery -A RealEarthStudio worker --loglevel=info

报错:

[2025-12-17 11:55:37,580: ERROR/MainProcess] Task handler raised error: ValueError(‘not enough values to unpack (expected 3, got 0)’)
billiard.einfo.RemoteTraceback:
Traceback (most recent call last):
File “D:\ProgramData\anaconda3\envs\realearthstudio_env\Lib\site-packages\billiard\pool.py”, line 362, in workloop
result = (True, prepare_result(fun(*args, **kwargs)))
^^^^^^^^^^^^^^^^^^^^
File “D:\ProgramData\anaconda3\envs\realearthstudio_env\Lib\site-packages\celery\app\trace.py”, line 683, in fast_trace_task
tasks, accept, hostname = _loc
^^^^^^^^^^^^^^^^^^^^^^^
ValueError: not enough values to unpack (expected 3, got 0)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File “D:\ProgramData\anaconda3\envs\realearthstudio_env\Lib\site-packages\billiard\pool.py”, line 362, in workloop
result = (True, prepare_result(fun(*args, **kwargs)))
^^^^^^^^^^^^^^^^^^^^
File “D:\ProgramData\anaconda3\envs\realearthstudio_env\Lib\site-packages\celery\app\trace.py”, line 683, in fast_trace_task
tasks, accept, hostname = _loc
^^^^^^^^^^^^^^^^^^^^^^^
ValueError: not enough values to unpack (expected 3, got 0)

这个报错点在celery/app/trace.pyfast_trace_task,在 Windows 上非常常见,本质通常不是你任务函数写错了,而是 Celery 在 Windows 的多进程(billiard/prefork)兼容性问题导致 worker 内部的局部变量_loc没有被正确初始化,于是解包失败。Celery 官方文档也明确提到不支持 Microsoft Windows。

  • 解决方案:Windows 下用solo池跑 worker,在settings.py中添加
CELERY_WORKER_POOL="solo"

即可正常运行。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/24 0:17:29

Java 线程知识点

Java线程是Java并发编程的核心,内容非常丰富且重要。这里为你梳理一个系统性的知识图谱和关键点详解,无论是面试还是日常开发都很有用。---一、Java线程的创建与管理1. 创建线程的三种核心方式 继承 Thread 类javaclass MyThread extends Thread {Overri…

作者头像 李华
网站建设 2026/6/24 7:53:36

直播间数据抓取终极方案:Live Room Watcher深度解析与实践指南

在直播电商和内容创作蓬勃发展的今天,如何精准获取直播间实时数据成为众多开发者和运营者面临的核心挑战。本文将为您完整解析一款功能强大的开源工具——Live Room Watcher,助您轻松应对多平台直播间数据监控需求。 【免费下载链接】live-room-watcher …

作者头像 李华
网站建设 2026/6/22 18:12:31

终极QQ截图独立版:完整屏幕捕捉解决方案

终极QQ截图独立版:完整屏幕捕捉解决方案 【免费下载链接】QQScreenShot 电脑QQ截图工具提取版,支持文字提取、图片识别、截长图、qq录屏。默认截图文件名为ScreenShot日期 项目地址: https://gitcode.com/gh_mirrors/qq/QQScreenShot 还在为繁琐的截图操作而…

作者头像 李华
网站建设 2026/6/22 10:50:06

Docker容器资源回收黑科技(Offload释放效率提升90%)

第一章:Docker容器资源回收黑科技概述 在高密度容器化部署环境中,资源的高效回收与再利用是保障系统稳定性和性能的关键。Docker虽然提供了基础的资源隔离与限制机制,但在复杂场景下,仍需借助“黑科技”手段实现精细化的内存、CPU…

作者头像 李华
网站建设 2026/6/24 3:22:44

为什么你的Cirq补全总出错?3分钟搞懂核心语法规则

第一章:Cirq 代码补全的语法规则概述Cirq 是由 Google 开发的用于编写、模拟和运行量子电路的 Python 框架。在使用 Cirq 进行开发时,代码补全功能能够显著提升编码效率。该功能依赖于清晰的语法规则与类型提示机制,使 IDE 能够准确推断变量类…

作者头像 李华
网站建设 2026/6/23 20:14:48

svg2gcode:从数字设计到物理制造的智能转换桥梁

svg2gcode:从数字设计到物理制造的智能转换桥梁 【免费下载链接】svg2gcode Convert vector graphics to g-code for pen plotters, laser engravers, and other CNC machines 项目地址: https://gitcode.com/gh_mirrors/sv/svg2gcode 在创意设计与物理制造的…

作者头像 李华