拓冰建站拓冰建站
首页 / 资讯中心 / 正文

5 分钟跑通第一个 Django 异步任务:django-tasks 完整上手指南与避坑手册

5 分钟跑通第一个 Django 异步任务django-tasks 完整上手指南与避坑手册【免费下载链接】django-tasksA backport of Djangos built in Tasks framework项目地址: https://gitcode.com/gh_mirrors/dj/django-tasksDjango 开发者最熟悉的抱怨大概是这个接口要等邮件发完才返回用户盯着加载圈转了三秒。django-tasks 是把 Django 正在内置的 Tasks 框架向后移植到当前版本的方案——它让你的既有项目用最小成本获得一套 Django 异步任务处理能力不需要引入 Celery 那套重型基础设施。本文按为什么用 → 怎么选 → 怎么跑 → 怎么维护的顺序讲清楚它。为什么用任务队列django-tasks 解决的两个痛点先看两个真实场景接口被慢操作绑架用户注册成功后要发欢迎邮件邮件服务抖了一下整个注册接口跟着卡住。批量计算拖累页面定时生成的报表查询和首页请求抢同一个数据库连接高峰期首页变慢。共同点都是请求里混进了不属于请求的活。django-tasks 的思路是把这类操作抽成任务定义、入队、执行、结果各归各位请求只负责把活交出去。它和 Celery 这类重型方案的区别决定了它适合谁django-tasksCelery 类重型方案定位Django 官方框架的向后移植统一的任务抽象成熟的第三方任务系统依赖只需 Django 本身需要部署 Redis / RabbitMQ 等消息代理运维后端可插拔默认零额外进程要管理 worker、队列、监控学习成本一个装饰器 一次enqueue()序列化、路由、重试、监控一整套适合场景中小流量、先把任务接口统一高吞吐、复杂工作流、跨系统分发关键认知django-tasks 首先解决的是标准化——把任务定义、入队、结果、信号统一到一套 Django 风格的接口里。业务代码只依赖抽象将来换更强的执行后端时改配置即可不用重写任务。但别急着写第一行代码。动手前有一个决策必须做对后端选哪个。先选后端选错后端的 2 个代价django-tasks 把任务是什么和任务谁来跑分开了执行者就是你要配置的后端backend。选错后端的典型代价有两个以为异步其实同步默认的ImmediateBackend在当前线程立即执行发任务那 3 秒请求照样被占住想用功能却被拒后端不支持priority、run_after等特性时框架会在入队前直接抛InvalidTask把配置错误拦在运行时之前。安装与配置只有三步python -m pip install django-tasks# settings.py INSTALLED_APPS [ # ... django_tasks, ] TASKS { default: { BACKEND: django_tasks.backends.immediate.ImmediateBackend } }官方自带的两个后端对比后端行为延迟执行run_after结果可重取适用场景ImmediateBackend当前线程立即执行❌❌开发环境、低流量先跑起来DummyBackend只存储、不执行✅仅限当前线程内存单元测试选型口诀开发/调试ImmediateBackend所见即所得断点能打到任务里写测试DummyBackend断言任务被正确入队而不真正执行副作用生产换用具备真实排队能力的后端第三方提供见文末生产建议。配置里还可以声明QUEUES允许的队列名和OPTIONS。后端是否支持某项特性可用default_task_backend.supports_defer、supports_priority、supports_get_result、supports_async_task四个布尔值在运行时 introspect配合 Django 的 system check 框架做上线前检查。后端定好、配置写进 settings跑通第一个任务只差两行代码。3 分钟跑通第一个任务定义一个任务# myapp/tasks.py from django_tasks import task task() def send_welcome_email(user_id: int) - None: # ... 发邮件逻辑 pass入队执行result send_welcome_email.enqueue(user_id1024) print(result.status) # SUCCESSFUL三个新手要知道的点task()包装后它不再是普通函数而是一个Task对象——不能直接send_welcome_email(1024)调用任务函数必须定义在模块顶层嵌套函数、lambda、类方法都不行校验会直接拒绝用ImmediateBackend时enqueue()返回时任务已经执行完毕这正是开发环境快速验证想要的行为。跑通之后你大概率会接着问三个问题怎么传参、怎么定时执行、怎么标优先级。让任务更聪明延迟执行、优先级与上下文 延迟任务run_afterdjango-tasks 延迟任务通过using()在入队时指定from datetime import timedelta from django.utils import timezone result send_welcome_email.using( run_aftertimezone.now() timedelta(hours1) ).enqueue(user_id1024)注意两点run_after必须是带时区的 aware datetimeDjango 默认USE_TZTrue后端需声明supports_defer否则定义时就会被拒。⚡ 优先级与队列task(priority10, queue_nameemails) def urgent_email(): ...priority是 -100 到 100 的整数越大越优先也可以用.using(priority...)按次修改queue_name决定进入哪个队列配合后端的QUEUES白名单使用backend参数可让不同任务走不同后端对应TASKS里的别名。任务上下文takes_context当任务需要知道我是第几次被尝试、我的结果 id 是什么时from django_tasks import task, TaskContext task(takes_contextTrue) def notify_with_retry(context: TaskContext, user_id: int) - None: # context.task_result本次执行对应的 TaskResult # context.attempt当前尝试次数 ...装饰器与using()可配置的参数一览参数传在哪作用priority装饰器 /.using()执行优先级-100 ~ 100queue_name装饰器 /.using()指定入队队列backend装饰器 /.using()指定执行后端run_after.using()最早执行时间takes_context仅装饰器注入TaskContext首参任务跑起来了接下来你肯定想验证它成功了吗返回值是什么之后还能查到吗追踪任务结果状态、返回值与重取enqueue()返回一个TaskResult生命周期共 4 个状态状态含义READY已入队等待执行或等待再次执行RUNNING正在执行SUCCESSFUL正常完成FAILED抛出异常或无法启动from django_tasks import TaskResultStatus if result.status TaskResultStatus.SUCCESSFUL: value result.return_value # 任务的返回值一个易踩的坑对未成功的任务访问return_value会抛ValueError——这是为了区分任务返回了 None和任务还没跑完。跨请求、跨任务重取结果靠result.id把它当不透明字符串最长 64 字符不要自己解析result send_welcome_email.get_result(result_id) # 按 id 取回本任务的结果 result default_task_backend.get_result(result_id) # 取回任意任务的结果 result.refresh() # 把本地缓存的状态从存储中刷新提醒重取能力取决于后端是否声明supports_get_resultDummyBackend支持结果存内存进程重启即失效ImmediateBackend不支持。能查到结果只完成了一半——任务迟早会失败怎么处理失败决定了它能不能进生产。任务失败了怎么排查重试、超时与状态监控拿到失败信息if result.status TaskResultStatus.FAILED: error result.errors[0] print(error.exception_class) # 异常类型惰性解析 print(error.traceback) # 完整 traceback 字符串直接进日志errors是列表但当前恒为单元素traceback是精简过的字符串足够定位问题但不含原始异常对象。重试需要你自己实现坦诚说明django-tasks 目前没有内置自动重试 N 次的策略result.attempts当前只会是 0 或 1。通用做法是利用task_finished信号或context.attempt判断失败后由业务层重新入队。好处是将来换到支持原生重试的后端时业务代码不用动。超时与状态监控TaskResult上有enqueued_at/started_at/finished_at/last_attempted_at四个时间戳配合status可以定期巡检跑了很久还没结束的任务ImmediateBackend没有独立 worker也就没有超时保护——长任务会阻塞调用它的那个请求长耗时任务必须换用真实排队后端框架注册了 Django system checkmanage.py check可以提前校验后端配置合法性。单个任务稳了接下来要解决的是量大以后怎么组织按类型分流、接入业务事件。规模化队列、信号与生产化建议队列配置TASKS { default: { BACKEND: django_tasks.backends.immediate.ImmediateBackend, QUEUES: [default, emails, reports], } }任务默认进入default队列声明QUEUES后入队到未声明的队列名会抛InvalidTask——拼写错误在入队时暴露而不是悄悄丢失设QUEUES为[]可关闭校验。三个生命周期信号信号触发时机task_enqueued任务入队时task_started任务即将开始执行前task_finished任务执行结束无论成败from django.dispatch import receiver from django_tasks.signals import task_finished receiver(task_finished) def alert_on_failure(sender, task_result, **kwargs): if task_result.status TaskResultStatus.FAILED: # 告警、落库、进死信队列…… ...框架已内置这三个信号的 debug/info 日志logger 名为django_tasks日志平台里直接可用。三条生产化建议生产换真实排队后端官方仓库目前只内置ImmediateBackend和DummyBackend两个DB / 消息队列类的第三方后端需另行选型接入用特性检查防事故部署前用supports_*检查 system check让功能不支持变成上线前报错而不是生产异常任务保持小且幂等一个任务只做一件事失败了敢于直接重入队。最后把高频踩坑点和常用 API 收成两张表上线前扫一遍。避坑清单与 API 速查表常见坑清单坑表现规避方式任务函数写在函数/类内部定义即报InvalidTask任务函数放模块顶层优先级传了小数或超范围InvalidTask用 -100 ~ 100 的整数run_after用 naive datetimeInvalidTask用timezone.now()等 aware 时间入队到未声明的队列名InvalidTask补进QUEUES或设[]关闭校验失败任务上读return_valueValueError先判status再取值把ImmediateBackend当真异步请求依旧被阻塞仅开发使用生产换排队后端在不支持的后端上重取结果NotImplementedError先查supports_get_result直接调用被装饰的任务TypeError用.enqueue()入队或.call()本地执行解析result.id当数字用行为不可预测当不透明字符串≤64 字符保存API 速查表需求写法安装启用pip install django-tasksINSTALLED_APPS加django_tasks定义任务task()可带priority/queue_name/backend/takes_context入队task.enqueue(*args, **kwargs)按次改选项task.using(priority..., queue_name..., run_after..., backend...).enqueue(...)取返回值result.return_value仅SUCCESSFUL刷新状态result.refresh()重取结果task.get_result(id)或default_task_backend.get_result(id)检查后端特性default_task_backend.supports_defer/supports_priority/supports_get_result/supports_async_task生命周期钩子task_enqueued/task_started/task_finished信号后端源码位置django_tasks/backends/base/immediate/dummydjango-tasks 的价值在于用最轻的成本把 Django 的任务抽象标准化——即使现在跑的还是 Immediate 后端流量上来时只需改TASKS配置业务代码一行不动。跑通第一个任务后剩下的工作就两件事选对后端然后盯着FAILED状态降为零。【免费下载链接】django-tasksA backport of Djangos built in Tasks framework项目地址: https://gitcode.com/gh_mirrors/dj/django-tasks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门