You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django(Daphne作为ASGI服务器)中异步并行运行任务?

解决Django+Daphne下异步任务并行的问题

你的asyncio.gather写法本身是正确的,出现请求挂起被杀死的问题,大概率是以下原因导致,对应解决方式如下:

1. 确保异步函数无未处理的同步阻塞代码

如果foo1/foo2/foo3内部包含同步阻塞操作(比如未用@sync_to_async包裹的ORM查询、本地文件IO、第三方同步SDK调用),会直接阻塞整个事件循环,导致请求超时被Daphne终止。

解决:所有同步代码必须用Django提供的@sync_to_async装饰,处理数据库操作时还需注意关闭旧连接:

from django.db import close_old_connections
from asgiref.sync import sync_to_async

# 封装适配数据库操作的同步转异步装饰器
def sync_to_async_db(func):
    @sync_to_async(thread_sensitive=True, executor="threadpool")
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        finally:
            close_old_connections()
    return wrapper

# 示例:将同步ORM查询转为异步
@sync_to_async_db
def fetch_model_data(param):
    from myapp.models import TargetModel
    return TargetModel.objects.filter(condition=param).values_list('field', flat=True)

# 确保foo类函数是纯异步逻辑,或正确包裹同步操作
async def foo1(p1):
    db_data = await fetch_model_data(p1)
    # 其他异步处理逻辑
    return db_data

2. 调整Daphne的请求超时参数

如果三个并行任务确实需要较长时间执行,Daphne默认的超时限制会杀死未完成的连接。启动Daphne时可以手动指定超时时间:

daphne --timeout 60 myproject.asgi:application

将60替换为你需要的超时秒数(如120、300)。

3. 确认异步视图的规范写法

确保你的API视图本身是异步视图,且正确调用并行任务:

from django.http import JsonResponse
import asyncio

async def my_api_view(request):
    p1 = request.GET.get('p1')
    p2 = request.GET.get('p2')
    p3 = request.GET.get('p3')
    r1, r2, r3 = await service_of_mine(p1, p2, p3)
    return JsonResponse({'r1': r1, 'r2': r2, 'r3': r3})

async def service_of_mine(p1, p2, p3):
    # 正确的并行执行写法
    return await asyncio.gather(foo1(p1), foo2(p2), foo3(p3))

4. 避免手动创建事件循环

如果代码中手动创建了新的事件循环(如asyncio.new_event_loop()),会和Daphne管理的全局事件循环冲突,导致任务无法正常调度。必须使用当前线程的默认事件循环,直接用await asyncio.gather(...)即可,不要手动创建或切换循环。


内容的提问来源于stack exchange,提问作者gabriel119435

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:30:54