面向 django.cn 的底层教程:从 ASGI 到 ORM 的一次完整往返

面向 django.cn 的底层教程:从 ASGI 到 ORM 的一次完整往返

很多人把 Django 当“黑盒”用。下面用一次请求的生命周期,把底层关键点串起来,便于做性能与可观测性优化。

  1. 入口与协议 Nginx/uvicorn -> ASGI。请求被封装为 scope(方法、路径、headers)、receivesend。Django 的 ASGIHandler 把它适配到中间件栈与视图。

  2. 中间件链 中间件本质是可组合的“环”:request -> (pre) -> view -> (post) -> response。写性能敏感中间件时,避免在 __call__ 里做阻塞 IO,优先使用异步视图与异步中间件:

class TraceMW:
    async def __call__(self, scope, receive, send):
        # 记录时间戳/trace-id,避免阻塞
        return await self.app(scope, receive, send)
  1. 视图与事务 Django 在数据库层使用按需连接,默认“自动提交”。高并发下建议显式控制边界,减少长事务:
from django.db import transaction
@transaction.atomic
def create_order(request):
    # 只把真正需要一致性的片段放进原子块
    ...
  1. ORM 到 SQL ORM QuerySet 是惰性的;常见坑是 N+1。使用 select_related(外键一对一)与 prefetch_related(多对多/反向)组合,配合 only/defer 精简列。读多写少的接口可加 queryset.explain() 审视索引命中。

  2. 连接池与异步 IO PostgreSQL 建议配合 pgbouncer;ASGI 下尽量把外部服务(对象存储、缓存、消息队列)切到异步客户端,避免阻塞事件循环。CPU 绑定任务(图像处理)用 Celery/RQ 下沉到任务队列。

  3. 缓存与幂等 热点列表页:模板片段缓存 + 细粒度失效。写接口加幂等键(如订单号 + nonce),避免重试造成重复写入。

  4. 可观测性 在中间件埋点:trace-id、SQL 耗时、缓存命中、外部调用统计。接入 OpenTelemetry/Prometheus,把 P95/P99 延迟与错误率纳入告警。

把这条链路打通后,你就能对“哪里慢、为什么慢、如何修”做到心中有数。

评论 0