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

Django开发服务器中间件sleep时长在多并发请求时倍增问题求解

问题原因

你的推测完全正确,问题根源就是Django默认的开发服务器(runserver)是单进程单线程同步模型,同一时间只能串行处理一个请求:

  1. 多个并发请求到达时,会先进入排队队列,等待前面的请求完全处理完成(包括你中间件里的sleep阶段)才会开始处理下一个
  2. 你测量的elapsed_time是当前请求get_response方法的执行时长,但没算请求排队等待的时间,所以后续排队的请求实际总耗时会叠加前面所有请求的sleep时长,出现成倍增长的情况。

你测试得到的请求耗时表现如下:
请求耗时测试结果

解决方案
  • 方案1:开启runserver多线程模式(改造成本最低)

Django 3.0及以上版本的runserver命令原生支持多线程参数,启动服务时添加--threads参数指定最大线程数即可:

python manage.py runserver --threads 10

开启后每个请求会分配到独立线程处理,sleep操作不会阻塞其他请求,即可实现每个请求总耗时约2秒的预期效果。

  • 方案2:使用支持并发的生产级服务器

如果需要更高的并发能力,可以用Uvicorn、Gunicorn这类支持多进程/多线程的服务器替代默认runserver,以Uvicorn为例:
首先安装依赖:

pip install uvicorn

随后启动服务:

uvicorn 你的项目名.asgi:application --host 127.0.0.1 --port 8000 --workers 2 --threads 8
中间件代码优化建议

你的现有代码在接口本身响应时长超过2秒时,会出现sleep传入负数的报错,建议加边界值处理:

import time
from django.utils.timezone import now
from django.http import HttpRequest

class SnailMiddleware:
    """ Middleware that throttle responses """
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request: HttpRequest):
        start = now()
        response = self.get_response(request)
        elapsed_time = (now() - start).total_seconds()
        # 避免传入负数导致报错
        sleep_time = max(0, 2 - elapsed_time)
        time.sleep(sleep_time)
        return response

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:18:02