Django+Nginx+Gunicorn部署后TTFB过高该如何排查解决?
排查与解决步骤
1. 优先定位耗时链路
先确认耗时出在哪一层,在视图中添加耗时统计代码,确认Django侧的总处理耗时:
import time def home(request): start = time.time() # 执行查询 posts = list(Post.objects.all()) query_cost = time.time() - start # 渲染模板 render_start = time.time() context = {'posts': posts} res = render(request, 'blog/home.html', context) render_cost = time.time() - render_start # 打印日志,线上可以直接输出到日志文件查看 print(f"查询耗时: {query_cost:.3f}s | 渲染耗时: {render_cost:.3f}s | 总视图耗时: {time.time()-start:.3f}s") return res
如果总视图耗时已经超过1s,说明问题出在Django服务侧,和Nginx/Gunicorn的配置无关。
2. 优化数据库查询与存储
- Sqlite为文件型数据库,不适合生产Web场景的并发读请求,其全局锁机制很容易导致查询排队,直接更换为PostgreSQL或MySQL可解决绝大多数数据库侧的耗时问题。
- 不要直接使用
Post.objects.all()拉取全量字段,根据模板实际用到的字段,用only()方法指定拉取字段,存在外键关联的场景搭配select_related/prefetch_related避免N+1查询:# 示例:只拉取模板需要的标题、发布时间、摘要字段 Post.objects.only('title', 'published_at', 'excerpt').all()
3. 新增视图缓存
如果首页内容不需要实时更新,直接添加Django视图缓存,缓存命中后无需执行查询和模板渲染,直接返回静态页面,耗时可降到10ms级:
from django.views.decorators.cache import cache_page # 缓存时长可根据内容更新频率调整,示例为缓存10分钟 @cache_page(60 * 10) @minified_response def home(request): context = { 'posts': Post.objects.all() } return render(request, 'blog/home.html', context)
4. 优化Gunicorn配置
2核2G服务器的Gunicorn worker数建议配置为2*CPU核数+1即5个worker,配合2个线程,避免worker不足导致请求排队:
gunicorn --workers=5 --threads=2 --bind=unix:/run/gunicorn.sock 你的项目名.wsgi:application
5. 优化Nginx配置
- 确认静态资源(js、css、图片)直接由Nginx返回,没有转发到Gunicorn处理。
- 确认Nginx和Gunicorn之间使用Unix套接字通信,而非TCP端口通信,降低网络开销。
内容的提问来源于stack exchange,提问作者Dheirya Tyagi
相关产品推荐
相关产品推荐

