Ubuntu 22.04 VPS上Django应用偶尔加载缓慢的诊断方法及常见配置错误排查
这种时快时慢的加载问题确实挺闹心的,尤其是网站还没流量的时候,排查起来更摸不着头绪。结合我处理Django+Gunicorn部署的经验,给你梳理一套诊断步骤和常见的配置坑,帮你定位问题:
一、先做基础诊断,定位慢请求根源
- 查看日志是第一步:
先盯紧Gunicorn的访问日志和错误日志,比如用tail -f /var/log/gunicorn/access.log(如果你的日志路径不同,换成实际的),看看慢请求对应的记录有没有超时、报错信息。同时打开Django的请求日志,要是开了DEBUG=True,可以直接看到每个请求的各阶段耗时;生产环境也可以配置Django的日志模块,记录每个请求的处理时间,重点看后台管理请求里哪一步拖了后腿。 - 检查系统资源波动:
用htop实时看CPU、内存占用,有没有某个进程突然飙高CPU,或者内存占满导致swap频繁读写(swap是磁盘,速度比内存慢100倍以上,一用swap肯定卡)。再用iotop看看磁盘I/O情况,要是数据库查询的时候磁盘读写占满,那大概率是数据库的锅。 - 测试数据库查询性能:
后台管理界面的慢请求大多和数据库有关,比如列表页的全表查询。你可以直接用数据库客户端(比如psql或mysql)执行后台常用的SQL,看看耗时。也可以在Django里临时用django.db.connection.queries打印某个请求的所有SQL,找出哪条查询拖慢了速度——重点看有没有没加索引的字段,或者关联查询太多导致的全表扫描。 - 验证Gunicorn的进程状态:
用ps aux | grep gunicorn看看worker进程数量是否合理。一般来说,Gunicorn的worker数建议设为2*CPU核心数 +1,但也要看VPS内存:如果内存小,worker开太多会导致内存不足,反而拖慢速度;如果worker太少,哪怕是你自己测试的几个请求也会排队,导致时快时慢。
二、常见的配置错误排查
- Gunicorn worker类型或数量不对:
要是用了默认的syncworker,但你的Django代码里有阻塞操作(比如同步调用外部API、慢数据库查询),那一个worker被卡住,其他请求就得等着,就会出现时快时慢的情况。这种情况要么换成gevent或eventlet的异步worker,要么根据系统资源适当增加worker数量。另外别忘了配置超时参数,比如--timeout 30,让Gunicorn自动杀掉超时的worker,避免占着资源不释放。 - 数据库缺少必要索引:
Django后台的列表页默认会查询全表数据,如果你的表有几千条以上的数据,又没给常用的过滤、排序字段加索引,第一次查询会很慢,之后可能因为数据库缓存变快,但缓存失效后又会变慢。赶紧给后台常用的字段(比如created_at、外键字段)加索引,Django里可以用models.Index来定义。 - 内存不足导致swap频繁使用:
很多便宜的VPS内存只有1G甚至更低,Gunicorn worker加上数据库进程很容易把内存占满,系统只能用swap来补。你可以用free -h看看swap的使用情况,如果Swap的Used经常不为0,要么升级VPS内存,要么减少Gunicorn的worker数量,避免内存过载。 - 没关闭DEBUG模式或没配置静态文件托管:
要是生产环境还开着DEBUG=True,Django会做很多额外操作,比如每次请求重新加载模板、不缓存静态文件,导致加载速度波动。而且生产环境应该用Nginx托管静态文件和媒体文件,让Gunicorn只处理动态请求——如果让Django自己处理静态文件,速度会非常慢,还容易出现时快时慢的情况。 - 没配置Django缓存:
后台管理的权限检查、模板渲染、数据统计等操作,如果每次都重新计算,会浪费很多时间。配置Redis或Memcached作为Django的缓存,把常用的查询结果、模板片段缓存起来,能大幅提升请求速度,减少波动。
三、其他可能的隐藏因素
- VPS宿主机资源共享问题:
有些廉价VPS是共享宿主机资源的,要是宿主机上其他用户突然占用大量CPU或磁盘,你的VPS性能就会波动。可以用vmstat看看系统的运行队列长度(r列),如果经常大于CPU核心数,大概率是宿主机资源不够了,这时候可能得换个靠谱的服务商。
内容的提问来源于stack exchange,提问作者Zinjifra
相关产品推荐
相关产品推荐

