记一次Django响应超慢的解决过程


Posted in Python onSeptember 17, 2020

在本地windows机器开发的Django项目运行正常,放到服务器上后响应超慢,花了一整个工作日没找到原因(非常绝望),又花了一整个周末才找到原因和临时解决办法,如果你的项目超慢可以参考一下解决思路。

排查过程:

1.怀疑是Python环境问题,到服务器上各种虚拟环境版本进行尝试,无果。

2.因为用了mysql数据库,开始用pymysql包连接改动了一些参数,担心是驱动问题导致数据库查的慢,更换mysqlclient包后,响应依旧慢。 

3.担心是有什么报错导致慢,于是艰难地开启了debug模式(由于用了pymysql所以开启debug模式也会有个报错),开启之后Django反应慢但没有任何报错,绝望~

4.都说用uwsgi中间件部署Django能加快响应速度,尝试之,没用。

5.作为运维人员的思路来了-整个链路监控吧,看看哪个环节慢了。在网上找到了django性能监控工具django-silk,装上之后发现只能看到请求耗时、sql查询耗时,sql查询耗时就几ms,也不慢啊,哭死!

6.是不是模板渲染或者代码有问题导致慢呢?

views.py中新建一个方法,不做任何处理,直接返回一个字符串,依旧慢!

7.从客户端发出请求到views.py处理计算这个过程很慢?

views.py的处理函数中增加print('test'),在浏览器中刷新网页后,查看Django输出,请求后要15s才能看到打印test。 

8.客户端到服务器网络慢?

服务器上新建一个空白的Django项目,运行在相同的端口上,反应正常,网络没问题。 

9.从Django接受到请求到views.py进行逻辑处理中间这个过程很慢!中间经过了django中间件middleware的处理,中间件导致的慢?

依次注释掉能注释的中间件,然后刷请求看浏览器发出请求到Django输出test的延时。

发现注释掉一个自定义的中间件后,Django很快就能输出test(看到了希望)。但是正常业务处理方法响应依旧慢。 

10.自定义中间做了什么,怎么会耗费这么长时间?

查看中间件代码,发现每次请求进来Django进来以后,都要查询数据库,判断当前的url路径是否需要进行认证。

但这也是一次简单的数据库查询而已啊,为什么会这么慢,而且前面django-silk中也显示数据库查询响应很快?

有一点可以肯定的是Django查数据库这个动作耗费了大量的时间! 

11.既然查询数据库这个过程慢,那抓个到数据库的包看一下?

一顿操作后发现,当接收到请求后服务器会给数据库发一点数据,然后过了10多s后又发了一堆数据,等这一堆数据打传输完后浏览器上网页就返回了,这肯定跟响应慢有联系!深挖!

linux上抓包保存到文件,下载到windows上用wireshark分析发现:当Django收到用户请求后,会主动与数据库主机进行tcp连接,三次握手很快就成功了,然后等待了15s才收到MySQL的greet信息,才进行后续的sql查询。这说明服务器很快就与数据库主机建立了连接,但mysql应用等了15s才响应。此处不理解的,可以详细看一下MySQL协议。 

12.由于公司的DB是由DBA负责的,而且现在也是周末,所以暂时没办法继续深挖DB原因。接下来怎么办呢,怎么解决Django响应慢的问题?

在服务器上继续抓包,想对比一下主机上其他应用查询MySQL有什么差异,发现其他应用连接MySQL时一样会有5s的延时。在分析包的过程中发现别的应用会发送ping这样的请求,咦,这不是心跳包吗?别的应用是不是有会话保持啥的?所以没看出来响应慢?

13.给Django也设置一下数据库长连接会话保持试一下?

百度上关于这块的文章都比较老了,都是通过sqlalchemy的连接池管理可以保持数据库的长连接和复用,要改源码操作起来比较麻烦。而且都是Django 1.4时代的解决办法了,现在都Django2.2了,官方有没有提供长连接的机制支持呢?百度和查官方文档后发现配置数据库连接信息时有个可选参数叫“CONN_MAX_AGE”,默认情况下值为0,即数据库查询连接用完之后就释放掉了,新的查询又要重新建立一次连接。

将参数设置为2个小时,再次实验。启动Django后,第一次请求还是很慢,但后面的请求就加快了,问题得到了临时解决!

Todo: 至于数据库为什么要15s才响应连接,这个上班后再找DBA了解具体原因。

寄语:这次问题排查真的很艰难,尝试了各种办法,花了很多时间,终于通过抓包找到了相关的原因。讲真,通过这次问题的排查让我有增加了很多Django的知识!希望能对你有所帮助。

20200531更新:连接mysql慢的原因

为什么mysql响应这么慢,百度一番后发现原因

mysql建立连接之前会根据连接的ip反向查找对应的主机名,这一步会涉及DNS反向解析(如果本地hosts文件没有指定就会找其他服务器查询),这个过程会消耗时间。

于是登陆数据库所在主机,通过命令"nslookup IP地址"分别查询本地IP和服务器IP,本地IP查询结果很快返回(不在一个网段找不到),服务器IP结果非常慢直到超时否没返回,这就解释了为什么前文【windows机器反应快,linux反应慢】的问题。至于为什么反向解析服务器IP这么慢,这个问题就不再继续挖下去了,应该是网管没有配置好相关的解析吧。

解决办法:禁用反向解析,找到mysql的配置文件/etc/my.cnf,增加一行配置,重启以后数据库响应速度就完美了。

[mysqld]
skip-name-resolve

既然这个反向解析这么耗时,为什么还要有这个流程呢?

还记得mysql的授权命令吗:

grant all priviledges on *.* to "user"@"%" identified by "pass"

@后面的%就代表任意的主机名和ip地址,对!这个地方是可以根据主机名来授权的,如果把反向DNS解析关掉了,这里就会有问题,授权的时候就只能根据ip进行授权啦~

到此这篇关于记一次Django响应超慢的解决过程的文章就介绍到这了,更多相关Django响应超慢内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python定时检查某个进程是否已经关闭的方法
May 20 Python
Python字符编码判断方法分析
Jul 01 Python
python paramiko模块学习分享
Aug 23 Python
浅谈用Python实现一个大数据搜索引擎
Nov 28 Python
TensorFlow模型保存/载入的两种方法
Mar 08 Python
python实现随机漫步算法
Aug 27 Python
Django中使用 Closure Table 储存无限分级数据
Jun 06 Python
python 日期排序的实例代码
Jul 11 Python
matplotlib命令与格式之tick坐标轴日期格式(设置日期主副刻度)
Aug 06 Python
浅析PEP570新语法: 只接受位置参数
Oct 15 Python
python 采用paramiko 远程执行命令及报错解决
Oct 21 Python
python实现多进程按序号批量修改文件名的方法示例
Dec 30 Python
Visual Studio Code搭建django项目的方法步骤
Sep 17 #Python
Windows下pycharm安装第三方库失败(通用解决方案)
Sep 17 #Python
PyCharm中关于安装第三方包的三个建议
Sep 17 #Python
Scrapy项目实战之爬取某社区用户详情
Sep 17 #Python
django跳转页面传参的实现
Sep 17 #Python
解决Ubuntu18中的pycharm不能调用tensorflow-gpu的问题
Sep 17 #Python
Django mysqlclient安装和使用详解
Sep 17 #Python
You might like
php iconv() : Detected an illegal character in input string
2010/12/05 PHP
input file获得文件根目录简单实现
2013/04/26 PHP
PHP连接MYSQL数据库实例代码
2016/01/20 PHP
php实现三级级联下拉框
2016/04/17 PHP
PHP实现爬虫爬取图片代码实例
2021/03/03 PHP
jQuery 操作下拉列表框实现代码
2010/02/22 Javascript
jquery.cookie.js 操作cookie实现记住密码功能的实现代码
2011/04/27 Javascript
下载文件个别浏览器文件名乱码解决办法
2013/03/19 Javascript
提取jquery的ready()方法单独使用示例
2014/03/25 Javascript
一个JS函数搞定网页标题(title)闪动效果
2014/05/13 Javascript
jQuery实现切换页面过渡动画效果
2015/10/29 Javascript
AngularJS 日期格式化详解
2015/12/23 Javascript
JS简单编号生成器实现方法(附demo源码下载)
2016/04/05 Javascript
基于JS实现导航条flash导航条
2016/06/17 Javascript
node.js实现快速截图
2016/08/27 Javascript
10分钟掌握XML、JSON及其解析
2020/12/06 Javascript
js滚轮事件兼容性问题需要注意哪些
2016/11/15 Javascript
angular中的cookie读写方法
2017/08/02 Javascript
js实现1,2,3,5数字按照概率生成
2017/09/12 Javascript
从vue基础开始创建一个简单的增删改查的实例代码(推荐)
2018/02/11 Javascript
Vue.js实现图片的随意拖动方法
2018/03/08 Javascript
微信小程序通过js实现瀑布流布局详解
2019/08/28 Javascript
JavaScript中reduce()的5个基本用法示例
2020/07/19 Javascript
Python3.5装饰器原理及应用实例详解
2019/04/30 Python
PyTorch 对应点相乘、矩阵相乘实例
2019/12/27 Python
Python3+Django get/post请求实现教程详解
2021/02/16 Python
德国宠物用品、宠物食品及水族馆网上商店:ZooRoyal
2017/07/09 全球购物
污水厂厂长岗位职责
2014/01/04 职场文书
奶茶专卖店创业计划书
2014/01/18 职场文书
元旦晚会邀请函
2014/01/27 职场文书
幼教求职信
2014/03/12 职场文书
学雷锋活动总结报告
2014/06/26 职场文书
2014离婚协议书范文两篇
2014/09/15 职场文书
学校运动会报道稿
2014/09/23 职场文书
公司财务会计主管应聘求职信
2014/09/26 职场文书
清洁员岗位职责
2015/02/15 职场文书