news 2026/7/2 5:34:13

【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/30 23:48:11

VSCode + Qiskit智能提示配置全攻略(从零到自动补全的终极指南)

第一章:VSCode Qiskit 的代码补全 在量子计算开发中,高效的编码体验离不开强大的代码补全功能。Visual Studio Code(VSCode)结合 Qiskit 开发插件,为开发者提供了智能提示、语法高亮和自动补全能力,显著提升…

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

GEO关键词AI排名优化哪家企业好

GEO关键词AI排名优化:至灵企业服务——您的理想之选在当今数字化营销竞争日益激烈的时代,企业要想在搜索引擎中脱颖而出,吸引更多潜在客户,关键词排名优化就显得尤为关键。特别是对于那些希望精准定位特定地理区域(GEO…

作者头像 李华
网站建设 2026/7/1 10:27:52

SeedVR2革命性突破:6GB显存实现专业级视频修复完整指南

在AI视频修复技术快速发展的当下,传统工具对高端硬件的严苛要求已成为技术普及的最大障碍。SeedVR2通过创新的模型优化方案,将显存需求从12GB以上降低至仅需6GB,让RTX 4060等主流显卡也能流畅运行专业级视频修复功能。这项突破性技术为短视频…

作者头像 李华
网站建设 2026/7/1 21:12:55

28、Linux使用技巧与优质信息源汇总

Linux使用技巧与优质信息源汇总 一、多屏幕分辨率设置 在Linux系统中,若你想在图形用户界面(GUI)中切换不同的屏幕分辨率,比如你常用1024 x 768分辨率,但在处理网页时想查看800 x 600甚至640 x 480分辨率下网页在浏览器中的显示效果,可按以下步骤操作: 1. 定位配置文…

作者头像 李华
网站建设 2026/7/1 23:10:36

30、Linux 系统使用与配置全解析

Linux 系统使用与配置全解析 1. 符号与数字相关 在 Linux 系统中,各种符号和数字有着特定的含义和用途。例如: | 符号 | 含义及用途 | | — | — | | *(星号) | 用于通配符扩展,在文件查找等操作中使用,如在命令中可表示匹配任意数量的任意字符,出现于 172、186 - …

作者头像 李华
网站建设 2026/7/1 21:19:27

Mybatis入门

1.创建数据库在数据库中创建一个表,命名随意,字段随意,但是一定要给id主键且自动递增!!!给表添加数据2.在idea中创建maven环境在新建项目中选择maven而不是java3.配置坐标打开maven项目中的pox.xml文件在de…

作者头像 李华