django应用基本优化方案
注: 以下方案只针对单机服务器
-
修改部署方式
不要用 manage.py runserver 做worker, django的默认启动方式使用的是python自带的WSGI服务器, 这个服务器性能和稳定没有很好的保证, 可以更换其他WSGI服务器, 如: uWSGI, gunicorn, gevent, tornado等, 很多方案会再加上nginx, nginx的强大主要体现在负载均衡,反向代理和静态资源处理, 单机服务器下主要使用nginx处理静态资源. (静态资源可以考虑走CDN, 图片走COS)
-
异步执行耗时任务
django默认以同步的方式处理请求, 一些耗时的请求, 会进入阻塞等待, 可以使用异步任务的方式执行耗时请求, 逻辑简单可以直接用thread和threading 另开启一个线程, 一般会使用使用成熟的框架, 如celery.
-
设置缓存
对于一些访问频繁高, 变更频率低的热点数据可以放入缓存, 下次请求时, 如果缓存中存在相同的数据可以从直接缓存中返回, 这样可以减少和数据库的交互. django自带的缓存机制, 可以设置全局缓存, 也可以进行单页缓存, 也可以不使用django的缓存机制, 手动指定读写步骤. 缓存数据库一般使用memcached和redis, 个人建议使用memcached, django原生支持,部署方便.
-
设置限流
服务器能处理的请求数有限,如果请求量特别大会导致服务器崩溃, 为了避免并维持一个可用的状态可以限制同一时间段, 可以处理的请求数. 常见的限流算法有:漏桶算法, 令牌桶算法. 与限流一起设置的往往还有频率, 用来防止爬虫之类的脚本高频率访问.
-
数据表添加索引
众所周知, 添加数据表索引可以提高数据查询的效率, 缺点是会影响写的效率.
-
处理N+1问题
这个问题是ORM框架通病, 用户表关联部门表, 查n个用户时执行的查询步骤: 查1次用户表, 再查n次部门表. django的反向查询可以尽量尝试用下面的方式:
Model.ojbects.select_related() 这就是内连接 Model.objects.prefetch_related('部门表') 这是2次查询