找回密码
 立即注册
首页 业界区 业界 Django+Celery 进阶:Celery可视化监控与排错 ...

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

腥狩频 8 小时前
一、Celery 命令行工具

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

  • 列出集群中在线的Celery Worker节点
  1. celery -A mysite status
  2. ### 大概10秒后,输出结果
  3. ->  celery@DESKTOP-MHHVBI3: OK
  4. 1 node online.
复制代码

  • 列出正在执行的Celery 任务
  1. celery -A mysite inspect active
  2. ### 输出结果
  3. ->  celery@DESKTOP-MHHVBI3: OK
  4.     - empty -
  5. 1 node online.
复制代码

  • 列出已注册的Celery 任务
  1. celery -A mysite inspect registered
  2. ### 输出结果示例
  3. ->  celery@DESKTOP-MHHVBI3: OK
  4.     * myapp_infra.tasks.cleanup_expired_data
  5.     * myapp_infra.tasks.send_daily_report
  6.     * myapp_system.tasks.login_log_task
  7.     * myapp_system.tasks.operation_log_task
  8.     * myapp_system.tasks.send_single_mail_task
  9. 1 node online.
复制代码

  • 显示Celery 统计数据
  1. celery -A mysite inspect stats
  2. ### 输出结果示例
  3. ->  celery@DESKTOP-MHHVBI3: OK
  4.     {
  5.         "broker": {
  6.             "alternates": [],
  7.             "connect_timeout": 4,
  8.             "failover_strategy": "round-robin",
  9.             "heartbeat": 0,
  10.             "hostname": "127.0.0.1",
  11.             "insist": false,
  12.             "login_method": null,
  13.             "port": 6379,
  14.             "ssl": false,
  15.             "transport": "redis",
  16.             "transport_options": {},
  17.             "uri_prefix": null,
  18.             "userid": null,
  19.             "virtual_host": "3"
  20.         },
  21.         "clock": "543",
  22.         "pid": 2316,
  23.         "pool": {
  24.             "implementation": "celery.concurrency.solo:TaskPool",
  25.             "max-concurrency": 1,
  26.             "max-tasks-per-child": null,
  27.             "processes": [
  28.                 2316
  29.             ],
  30.             "put-guarded-by-semaphore": true,
  31.             "timeouts": []
  32.         },
  33.         "prefetch_count": 32,
  34.         "rusage": "N/A",
  35.         "total": {
  36.             "myapp_infra.tasks.cleanup_expired_data": 3,
  37.             "myapp_system.tasks.login_log_task": 36
  38.         },
  39.         "uptime": 541
  40.     }
  41. 1 node online.
复制代码
小结:

  • 以上命令支持 --timeout参数,例如在命令后加上--timeout 3
  • 参考资料:Celery 监控
二、Celery 图形监控

Celery Flower 图形监控

Celery Flower 是一个用于监控和管理 Celery 任务的开源 Web 应用程序,它提供了实时的任务状态监控、任务执行图表、工作者信息、任务追踪和任务日志等功能。
安装
  1. pip install flower
复制代码
基本使用

Celery Flower 服务启动命令:进入根目录(包含manage.py文件的目录)执行
  1. celery -A mysite flower --port=5555
复制代码
访问 http://:5555 查看Celery 图形监控

  • 点击 Workers 查看 Celery Worker 状态
1.png


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


  • 点击 Broker 查看 Redis 状态
3.png

与Django项目集成

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

点击查看集成代码示例
三、Redis 图形监控

Redis一般作为Celery的消息中间件 (Broker),负责接收任务生产者发送的消息并将任务存入队列。
安装工具:Another Redis Desktop Manager,是一个Redis的图形管理界面工具。下载地址
解压即可使用。连接Redis 服务器后,查看celery队列中的任务数。

  • 如果没有celery键,表示当前没有等待的Celery任务
5.png

四、Celery 排错

PermissionError权限错误

错误信息
  1. [2025-04-12 22:53:48,435: INFO/MainProcess] Task tasks.add[6d0cc2d2-0a84-4a4d-b5e7-e86a4bd9b625] received
  2. [2025-04-12 22:53:48,436: ERROR/SpawnPoolWorker-6] Pool process <billiard.pool.Worker object at 0x0000027D686A33D0> error: PermissionError(13, '拒绝访问。', None, 5, None)
  3. Traceback (most recent call last):
复制代码
解决方法
  1. # 在Windows系统中,prefork 多进程模式可能导致权限冲突。改用单进程模式启动--pool=solo
  2. celery -A tasks worker --loglevel=INFO --pool=solo
复制代码
AppRegistryNotReady 错误

错误信息
  1. 2025-05-17 18:33:13,886 INFO D:\workspace_python\mars-mgn\mysite\myapp_system\tasks.py changed, reloading.
  2. Traceback (most recent call last):
  3. ...
  4.   File "D:\workspace_python\mars-mgn\venv\Lib\site-packages\django\apps\registry.py", line 138, in check_apps_ready
  5.     raise AppRegistryNotReady("Apps aren't loaded yet.")
  6. django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
复制代码
解决方法

  • 分析:Celery初始化与Django启动顺序问题:在celery.py中通过app.autodiscover_tasks()自动发现任务时,可能过早加载包含Django模型的任务模块,而Django的INSTALLED_APPS尚未完全初始化
  • 避免在任务模块顶部直接导入Django模型。将模型导入操作移至任务函数内部
  1. # myapp_system/tasks.py
  2. from celery import shared_task
  3. from django.core.mail import send_mail
  4. @shared_task
  5. def send_email_task(subject, message, from_email, recipient_list):
  6.     # 导入操作移至任务函数内部:延迟导入模型和序列化器
  7.     from .mail_log.serializers import MailLogSaveSerializer
  8.     from .models import SystemMailLog
  9.    
  10.     # 发送邮件逻辑
  11.     send_mail(subject, message, from_email, recipient_list)
  12.     return "邮件发送成功"
复制代码
任务参数

错误信息
  1. 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 中明确配置
  1. # 设置 Django 时区
  2. TIME_ZONE = 'Asia/Shanghai'
  3. USE_TZ = True
  4. # 配置 Celery 时区
  5. CELERY_TIMEZONE = 'Asia/Shanghai'
  6. # MySQL数据库连接字符串中添加时区参数
  7. DATABASES = {
  8.     "default": {
  9.         "ENGINE": "django.db.backends.mysql",
  10.                 # ...
  11.         "OPTIONS": {"init_command": "SET time_zone='+08:00'"},
  12.     }
  13. }
复制代码

  • Celery Worker 所在服务器系统时区为
  1. # 查看系统时区
  2. timedatectl | grep "Time zone"
  3. # 设置时区
  4. timedatectl set-timezone Asia/Shanghai
复制代码
您正在阅读的是《Django从入门到实战》专栏!关注不迷路~

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册