记一次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写个下载teahour音频的小脚本
May 08 Python
关于反爬虫的一些简单总结
Dec 13 Python
Python中GeoJson和bokeh-1的使用讲解
Jan 03 Python
python三方库之requests的快速上手
Mar 04 Python
谈谈Python中的while循环语句
Mar 10 Python
用django-allauth实现第三方登录的示例代码
Jun 24 Python
Python的bit_length函数来二进制的位数方法
Aug 27 Python
Python中six模块基础用法
Dec 08 Python
python绘制动态曲线教程
Feb 24 Python
python函数中将变量名转换成字符串实例
May 11 Python
Django models文件模型变更错误解决
May 11 Python
用Python自动清理电脑内重复文件,只要10行代码(自动脚本)
Jan 09 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
全国FM电台频率大全 - 16 河南省
2020/03/11 无线电
如何获得PHP相关资料
2006/10/09 PHP
六酷社区论坛HOME页清新格调免费版 下载
2007/03/07 PHP
帝国cms目录结构分享
2015/07/06 PHP
ThinkPHP表单数据智能写入create方法实例分析
2015/09/27 PHP
24款非常有用的 jQuery 插件分享
2011/04/06 Javascript
javascript 手动给表增加数据的小例子
2013/07/10 Javascript
js日期、星座的级联显示代码
2014/01/23 Javascript
js闭包的用途详解
2014/11/09 Javascript
ajax如何实现页面局部跳转与结果返回
2015/08/24 Javascript
javascript html5 canvas实现可拖动省份的中国地图
2016/03/11 Javascript
JS只能输入正整数的简单实例
2016/10/07 Javascript
ES6 Promise对象概念与用法分析
2017/04/01 Javascript
BootStrap Fileinput插件和Bootstrap table表格插件相结合实现文件上传、预览、提交的导入Excel数据操作步骤
2017/08/07 Javascript
浅谈angular2 组件的生命周期钩子
2017/08/12 Javascript
Vue中添加手机验证码组件功能操作方法
2017/12/07 Javascript
解决Vue 浏览器后退无法触发beforeRouteLeave的问题
2017/12/24 Javascript
vue 配置多页面应用的示例代码
2018/10/22 Javascript
微信小程序获取用户openid的实现
2018/12/24 Javascript
vue中实现上传文件给后台实例详解
2019/08/22 Javascript
Python正则简单实例分析
2017/03/21 Python
python使用xlsxwriter实现有向无环图到Excel的转换
2018/12/12 Python
python调用java的jar包方法
2018/12/15 Python
Python socket模块ftp传输文件过程解析
2019/11/05 Python
利用CSS3的transition属性实现滑动效果
2015/08/05 HTML / CSS
详解Canvas事件绑定
2018/06/27 HTML / CSS
美国男女折扣服饰百货连锁店:Stein Mart
2017/05/02 全球购物
全球速卖通法国在线交易平台:AliExpress法国
2017/07/07 全球购物
德国机车企业:FC-Moto
2017/10/27 全球购物
戴尔新加坡官网:Dell Singapore
2020/12/13 全球购物
发展党员工作情况汇报
2014/10/28 职场文书
2015年度培训工作总结范文
2015/04/02 职场文书
复试通知单模板
2015/04/24 职场文书
画展观后感
2015/06/17 职场文书
Django操作cookie的实现
2021/05/26 Python
Zabbix对Kafka topic积压数据监控的解决方案
2022/07/07 Servers