使用py-spy解决scrapy卡死的问题方法
背景
在使用scrapy爬取东西的时候,使用crontab定时的启动爬虫,但是发现机器上经常产生很多卡死的scrapy进程,一段时间不管的话,会导致有10几个进程都卡死在那,并且会导致数据产出延迟。
问题定位
使用py-spy这个非常好用的python性能分析工具来进行排查,py-spy可以查看一个python进程函数调用用时,类似unix下的top命令。所以我们用这个工具看看是什么函数一直在执行。
首先安装这个工具
pip install py-spy
用py-spy看看scrapy哪个函数执行时间长
# 先找到这个卡死的scrapy进程的pid ps -ef |grep scrapy # 启动 py-spy 观察这进程 py-spy top --pid 53424
首先我们按3,按owntime进行排序,这个表示函数自身执行的时间,可以看到read这个函数执行的时间最长,那看来是io导致的,程序中的io行为就是读写磁盘和网络io,磁盘读写一般不会有问题,所以初步定位是网络io导致的。
接下来进行进一步确认,再按4,按totaltime 所有子函数执行时间总和进行排序,可以看到是在process_item和download,upload_image这些主流程函数的执行时间比较长,这一步是先把图片下载到本地,然后上传到静床,看来是下载这步从网络中read数据时出现了问题,进一步追踪代码。
看下download的函数的代码:
if filename == '': filename = os.path.basename(url) path = path + '/' + filename try: res = request.urlretrieve(url,filename=path) print(url,res) return path except exception as e: print('download img failed') print(e) return false
可以看到用了urllib这个库里面request.urlretrieve函数,这个函数是用来下载文件的,去看看python官网文档的函数说明,发现里面没有超时时间这个参数,所以是由于没有超时时间,导致一直在read,进而使得进程卡死。
urllib.request.urlretrieve(url, filename=none,reporthook=none,data=none)
解决方案
使用另一种方式来下载图片,使用支持超时时间的urlopen函数,封装成一个自定义的url_retrieve,这样就不再会出现没有超时导致的卡死问题了。
def url_retrieve(self,url, path): r = request.urlopen(url, timeout=5) res = false with open(path,"wb") as f: res = f.write(r.read()) f.flush() f.close() return res
到此这篇关于使用py-spy解决scrapy卡死的问题方法的文章就介绍到这了,更多相关scrapy卡死内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
上一篇: 哈啰出行如何关闭语音提示?
推荐阅读
-
html5的input的required使用中遇到的问题及解决方法
-
Python使用循环神经网络解决文本分类问题的方法详解
-
web.py在SAE中的Session问题解决方法(使用mysql存储)
-
Mysql5.7中使用group concat函数数据被截断的问题完美解决方法
-
使用Python的SymPy库解决数学运算问题的方法
-
win2003下PHP使用preg_match_all导致apache崩溃问题的解决方法
-
ubuntu14.04 使用中遇到的问题及解决方法集锦
-
PHP的foreach中使用引用时需要注意的一个问题和解决方法
-
jQuery中ajax的使用与缓存问题的解决方法
-
Android Multidex使用,方法数超过“65536”问题的解决方式