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

Docker部署的Django应用启动后HTTP请求响应缓慢求助

问题描述

本地运行Docker化的Django+Postgres应用,启动后首次访问任何localhost URL都需要3-4分钟才能响应,之后恢复正常(响应时间100-200ms),特征如下:

  • 无重型进程运行,所有URL(admin、swagger等)均出现该情况
  • 卡顿期间CPU负载明显升高,新旧机器都存在,排除硬件问题
  • 部署环境无此问题
  • 卡顿期间docker-compose exec或run命令仍正常工作

注:可提供线程转储或其他日志,目前无明确排查方向


docker-compose配置(local.yml)

version: '3'

volumes:
  backend_local_postgres_data: {}
  backend_local_postgres_data_backups: {}

services:
  django: &django
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: backend_local_django
    container_name: backend_local_django
    depends_on:
      - postgres
    volumes:
      - .:/app:z
    env_file:
      - ./.envs/.local/.django
      - ./.envs/.local/.postgres
    ports:
      - "8000:8000"
    command: /start

  postgres:
    build:
      context: .
      dockerfile: ./compose/production/postgres/Dockerfile
    image: backend_production_postgres
    container_name: backend_local_postgres
    volumes:
      - backend_local_postgres_data:/var/lib/postgresql/data:Z
      - backend_local_postgres_data_backups:/backups:z
    env_file:
      - ./.envs/.local/.postgres

应用启动日志

(venv) docker-compose -f local.yml up
[+] Running 1/1
 - Network backend_default  Created                                                                                                                                                                                          0.6s 
[+] Running 3/34T19:42:41+01:00" level=warning msg="mount of type `volume` should not define `bind` option"
 - Network backed_default            Created                                                                                                                                                                                0.6s
 - Container backend_local_postgres  Created                                                                                                                                                                                0.1s
 - Container backend_local_django    Created                                                                                                                                                                                0.1s
Attaching to backend_local_django, backend_local_postgres
| 
| PostgreSQL Database directory appears to contain a database; Skipping initialization
| 
| 2023-02-04 18:42:42.783 UTC [1] LOG:  starting PostgreSQL 14.6 (Debian 14.6-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
| 2023-02-04 18:42:42.783 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
| 2023-02-04 18:42:42.783 UTC [1] LOG:  listening on IPv6 address "::", port 5432
| 2023-02-04 18:42:42.792 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
| 2023-02-04 18:42:42.804 UTC [27] LOG:  database system was shut down at 2023-02-01 11:55:22 UTC
| 2023-02-04 18:42:42.814 UTC [1] LOG:  database system is ready to accept connections
| PostgreSQL is available
| Operations to perform:
|   Apply all migrations: account, admin, auth, authtoken, constructor, contenttypes, django_celery_beat, sessions, sites, socialaccount, users
| Running migrations:      
|   No migrations to apply.
| WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
|  * Running on all addresses (0.0.0.0)
|  * Running on http://127.0.0.1:8000  
|  * Running on http://172.18.0.3:8000 
| Press CTRL+C to quit
|  * Restarting with watchdog (inotify)
| Performing system checks...
| 
| System check identified no issues (0 silenced).
| 
| Django version 4.0.8, using settings 'config.settings.local'
| Development server is running at http://0.0.0.0:8000/
| Using the Werkzeug debugger (http://werkzeug.pocoo.org/)
| Quit the server with CONTROL-C.
|  * Debugger is active!
|  * Debugger PIN: 130-235-671

依赖包配置(requirements.txt)

base.txt

pytz==2022.6
python-slugify==7.0.0
Pillow==9.3.0
argon2-cffi==21.3.0
redis==4.3.5
hiredis==2.0.0
celery==5.2.7
django-celery-beat==2.4.0
flower==1.2.0

# Django
django==4.0.8
django-environ==0.9.0
django-model-utils==4.3.1
django-allauth==0.51.0
django-crispy-forms==1.14.0
crispy-bootstrap5==0.7
django-redis==5.2.0
# Django REST Framework
djangorestframework==3.14.0
django-cors-headers==3.13.0
djangorestframework-simplejwt==5.2.2
drf-yasg==1.21.4

local.txt

-r base.txt

Werkzeug[watchdog]==2.2.2
ipdb==0.13.9
psycopg2-binary==2.9.5
watchfiles==0.18.1

# Testing
mypy==0.982
django-stubs==1.12.0
pytest==7.2.0
pytest-sugar==0.9.6
djangorestframework-stubs==1.7.0

# Documentation
sphinx==5.3.0
sphinx-autobuild==2021.3.14

# Code quality
flake8==5.0.4
flake8-isort==5.0.3
coverage==6.5.0
black==22.10.0
pylint-django==2.5.3
pylint-celery==0.3
pre-commit==2.20.0

# Django
factory-boy==3.2.1
django-debug-toolbar==3.7.0
django-extensions==3.2.1
django-coverage-plugin==2.0.4
pytest-django==4.5.2

排查与解决方案

结合症状,重点排查以下几个方向:

1. Django首次启动的代码预热与模块加载

首次请求时Django会懒加载所有相关模块,若项目依赖多、模块复杂,可能导致首次加载耗时过长,CPU升高。

  • 解决办法:
    • 在启动脚本中添加预热逻辑,比如启动后立即发送一个HEAD请求到首页或admin页面,触发模块预加载
    • 优化settings中的INSTALLED_APPS,移除本地开发不需要的应用
    • 检查是否有自定义中间件或信号在首次请求时执行了耗时操作

2. Docker文件系统绑定挂载的性能问题

本地开发中使用.:/app绑定挂载,Docker在同步大量文件时可能产生性能瓶颈,尤其是首次访问时需要读取大量静态文件或模块文件。

  • 解决办法:
    • 添加.dockerignore文件,排除不必要的文件(如__pycache__、.git、日志文件等),减少文件同步量
    • 尝试使用Docker卷代替绑定挂载,或调整Docker文件共享设置(如Docker Desktop中启用高性能文件共享选项)

3. PostgreSQL连接与初始化延迟

虽然日志显示PostgreSQL已就绪,但首次连接时可能存在隐式的数据库初始化或连接池建立过程。

  • 解决办法:
    • 检查Django数据库配置中的CONN_MAX_AGE,设置为合理值(如60),避免每次请求重新建立连接
    • 在启动脚本中使用wait-for-it等工具,等待PostgreSQL完全就绪后再启动Django,而不仅仅依赖depends_on

4. Werkzeug调试服务器的性能问题

本地开发使用的Werkzeug调试服务器并非生产级服务器,首次请求时会执行额外的调试检查、代码重载准备等操作。

  • 解决办法:
    • 替换为gunicorn作为本地开发服务器,测试是否还存在首次卡顿问题
    • 在启动命令中添加--noreload,关闭Werkzeug的自动重载功能

5. 依赖包的初始化开销

部分依赖包在首次导入时会执行耗时操作(如redis连接初始化、celery配置加载等)。

  • 解决办法:
    • 检查settings.py中是否有在模块级别执行的耗时操作(如提前初始化客户端、加载大量数据),将这些逻辑延迟到首次请求或异步执行
    • 暂时注释掉非必要的依赖包(如celery、flower),测试是否卡顿消失,逐步排查定位问题包

排查工具建议

  • 使用docker stats查看卡顿期间容器的CPU、内存使用情况,确认是Django容器还是PostgreSQL容器导致CPU升高
  • 在Django中添加日志,记录首次请求各阶段的耗时(如中间件处理、视图渲染、数据库查询等)
  • 使用py-spy生成线程转储,查看卡顿期间Django进程正在执行的函数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:00:51