异步视图未提升吞吐量的主因是未正确启用ASGI服务器:必须用uvicorn等ASGI服务器启动(如uvicorn myproject.asgi:application),禁用runserver或WSGI模式,并确保使用a开头的异步ORM方法、异步中间件及合理配置Uvicorn参数。

异步视图写对了,但吞吐量没涨?先确认 ASGI 服务器是否真在跑
很多开发者写了 async def 视图,却没提升吞吐量,根本原因是还在用 runserver 或 WSGI 模式(如 Gunicorn + WSGI)启动。Django 的开发服务器 runserver 默认是同步的,不支持异步视图;而 WSGI 协议本身是同步模型,强制把异步函数“降级”为同步执行。
必须用 ASGI 服务器启动,且确保它实际接管了请求:
- 检查启动命令是否为
uvicorn myproject.asgi:application,不是python manage.py runserver - 确认
asgi.py文件中调用了get_asgi_application(),且未被中间件意外包裹成同步包装器 - 启动后访问时,
uvicorn日志应显示类似Uvicorn running on http://... (Press CTRL+C to quit),而不是 Django 的Starting development server... - 在视图里加一行
import asyncio; print(f"Running in thread: {threading.current_thread().name}, loop: {asyncio.get_running_loop()}"),输出应含asyncio循环,而非ThreadPoolExecutor
Uvicorn 启动参数直接影响并发能力
uvicorn 不是开箱即用就高性能,几个关键参数不调,等于白切异步:
-
--workers 4:推荐设为 CPU 核心数 × 1~2,单 worker 无法压满多核;但别盲目堆高,超过 8 可能因进程间调度反拖慢 -
--http h11或--http httptools:后者更快但需额外安装httptools;若用 WebSocket,必须选httptools -
--limit-concurrency 1000:防突发连接打爆内存;配合--limit-max-requests 10000可缓解长连接泄漏 -
--timeout-keep-alive 5:降低空闲连接占用,尤其在 Nginx 前置时,避免 Nginx 和 Uvicorn keep-alive 超时错配
错误示例:uvicorn asgi:application(无任何参数)——默认只启 1 个 worker、无并发限制,高并发下迅速排队。
立即学习“Python免费学习笔记(深入)”;
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
数据库查询仍是最大瓶颈,ORM 异步方法必须显式调用
写了 async def 视图,但里面还用 .filter() 或 .all(),那整个请求依然会阻塞。Django 5.0 的异步 ORM 不是自动切换的,必须用带 a 前缀的方法:
- 用
await MyModel.objects.afilter(...)替代.filter(...) - 用
await obj.asave()替代obj.save() - 关联预加载必须用
aprefetch_related()或aselect_related(),否则async for遍历时仍触发同步 N+1 查询 - 注意:PostgreSQL 必须配
asyncpg驱动,SQLite 和 MySQL 官方异步驱动仍不稳定,生产环境慎用
常见误操作:queryset = MyModel.objects.filter(...); async for obj in queryset: —— 这里 filter 是同步的,已阻塞一次;async for 仅对异步 QuerySet 有效。
别让中间件或缓存拖垮异步链路
一个同步中间件就能让整个异步视图退化成同步执行。Django 5.0 支持异步中间件,但必须显式声明:
- 中间件类里定义
async def process_request(self, request),不能是def process_request -
cache_page装饰器目前仍是同步的,会阻塞事件循环;改用aiocache或直接在视图里用await cache.aget()/await cache.aset() - 日志中间件若调用
print()或同步文件写入,也会卡住;优先走异步日志库(如structlog+aiologger)或发到消息队列 - CSRF、Session 中间件默认已适配异步,但自定义 session backend 若含同步 I/O(如文件型),需重写为异步版本
最容易被忽略的一点:Nginx 到 Uvicorn 的连接超时设置。若 Nginx 的 proxy_read_timeout 小于 Uvicorn 的 --timeout-keep-alive,连接会被提前断开,导致客户端收到 502 Bad Gateway,看似是异步失败,实则是反向代理配置失配。

















