Django+Celery 进阶:Celery可视化监控与排错

64 阅读4分钟

、Celery 命令行工具 Celery 命令行工具可用去查看Celery的运行状态。打开一个终端窗口,进入项目目录(与manage.py同级),运行以下命令

列出集群中在线的Celery Worker节点 celery -A mysite status

大概10秒后,输出结果

-> celery@DESKTOP-MHHVBI3: OK

1 node online. 列出正在执行的Celery 任务 celery -A mysite inspect active

输出结果

-> celery@DESKTOP-MHHVBI3: OK - empty -

1 node online. 列出已注册的Celery 任务 celery -A mysite inspect registered

输出结果示例

-> celery@DESKTOP-MHHVBI3: OK * myapp_infra.tasks.cleanup_expired_data * myapp_infra.tasks.send_daily_report * myapp_system.tasks.login_log_task * myapp_system.tasks.operation_log_task * myapp_system.tasks.send_single_mail_task

1 node online. 显示Celery 统计数据 celery -A mysite inspect stats

输出结果示例

-> celery@DESKTOP-MHHVBI3: OK { "broker": { "alternates": [], "connect_timeout": 4, "failover_strategy": "round-robin", "heartbeat": 0, "hostname": "127.0.0.1", "insist": false, "login_method": null, "port": 6379, "ssl": false, "transport": "redis", "transport_options": {}, "uri_prefix": null, "userid": null, "virtual_host": "3" }, "clock": "543", "pid": 2316, "pool": { "implementation": "celery.concurrency.solo:TaskPool", "max-concurrency": 1, "max-tasks-per-child": null, "processes": [ 2316 ], "put-guarded-by-semaphore": true, "timeouts": [] }, "prefetch_count": 32, "rusage": "N/A", "total": { "myapp_infra.tasks.cleanup_expired_data": 3, "myapp_system.tasks.login_log_task": 36 }, "uptime": 541 }

1 node online. 小结:

以上命令支持 --timeout参数,例如在命令后加上--timeout 3 参考资料:Celery 监控 二、Celery 图形监控 Celery Flower 图形监控 Celery Flower 是一个用于监控和管理 Celery 任务的开源 Web 应用程序,它提供了实时的任务状态监控、任务执行图表、工作者信息、任务追踪和任务日志等功能。

安装

pip install flower 基本使用 Celery Flower 服务启动命令:进入根目录(包含manage.py文件的目录)执行

celery -A mysite flower --port=5555 访问 http://:5555 查看www.hefeilaws.com/ Celery 图形监控

点击 Workers 查看 Celery Worker 状态 image-20250525113618659

点击 Tasks 查看当前及后来的任务(不会显示以前的任务)。另外,通过观察任务列表的变化,判断 Celery Beat 的状态是否正常。 image-20250525110933420

点击 Broker 查看 Redis 状态 image-20250525113632394

与Django项目集成 对于Django+Vue3的前后端分离项目,使用iframe(内联框架) HTML 元素,可将网页嵌入其他网页。实现将Celery Flower 集成到Django项目中。

image-20250716143830162

点击查看集成代码示例

三、Redis 图形监控 Redis一般作为Celery的消息中间件 (Broker),负责接收任务生产者发送的消息并将任务存入队列。

安装工具:Another Redis Desktop Manager,是一个Redis的图形管理界面工具。下载地址

解压即可使用。连接Redis 服务器后,查看celery队列中的任务数。

如果没有celery键,表示当前没有等待的Celery任务 image-20250525104650853

四、Celery 排错 PermissionError权限错误 错误信息

[2025-04-12 22:53:48,435: INFO/MainProcess] Task tasks.add[6d0cc2d2-0a84-4a4d-b5e7-e86a4bd9b625] received [2025-04-12 22:53:48,436: ERROR/SpawnPoolWorker-6] Pool process <billiard.pool.Worker object at 0x0000027D686A33D0> error: PermissionError(13, '拒绝访问。', None, 5, None) Traceback (most recent call last): 解决方法

在Windows系统中,prefork 多进程模式可能导致权限冲突。改用单进程模式启动--pool=solo

celery -A tasks worker --loglevel=INFO --pool=solo AppRegistryNotReady 错误 错误信息

2025-05-17 18:33:13,886 INFO D:\workspace_python\mars-mgn\mysite\myapp_system\tasks.py changed, reloading. Traceback (most recent call last): ... File "D:\workspace_python\mars-mgn\ www.hefeilaws.com/ venv\Lib\site-packages\django\apps\registry.py", line 138, in check_apps_ready raise AppRegistryNotReady("Apps aren't loaded yet.") django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet. 解决方法

分析:Celery初始化与Django启动顺序问题:在celery.py中通过app.autodiscover_tasks()自动发现任务时,可能过早加载包含Django模型的任务模块,而Django的INSTALLED_APPS尚未完全初始化 避免在任务模块顶部直接导入Django模型。将模型导入操作移至任务函数内部

myapp_system/tasks.py

from celery import shared_task from django.core.mail import send_mail

@shared_task def send_email_task(subject, message, from_email, recipient_list): # 导入操作移至任务函数内部:延迟导入模型和序列化器 from .mail_log.serializers import MailLogSaveSerializer from .models import SystemMailLog

# 发送邮件逻辑
send_mail(subject, message, from_email, recipient_list)
return "邮件发送成功"

任务参数 错误信息

celery.beat.SchedulingError: Couldn't apply scheduled task daily_cleanup_expired_data: cleanup_expired_data() takes 0 positional arguments but 1 was given 解决方法

分析:args 和 kwargs 参数是传递给任务。若定义任务时没有定义接收参数,但却传递了arsg或kwargs参数,则Celery Beat 会报错 修改任务定义的代码,然后重启Celery worker和 beat。 时区 建议使用统一的时区,例如全部统一为东八区

在 settings.py 中明确配置

设置 Django 时区

TIME_ZONE = 'Asia/Shanghai' USE_TZ = True

配置 Celery 时区

CELERY_TIMEZONE = 'Asia/Shanghai'

MySQL数据库连接字符串中添加时区参数

DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", # ... "OPTIONS": {"init_command": "SET time_zone='+08:00'"}, } } Celery Worker 所在服务器系统时区为

查看系统时区

timedatectl | grep "Time zone"

设置时区

timedatectl set-timezone Asia/Shanghai