使用py-spy解决scrapy卡死的问题方法


Posted in Python onSeptember 29, 2020

背景

在使用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导致的。

使用py-spy解决scrapy卡死的问题方法

接下来进行进一步确认,再按4,按TotalTIme 所有子函数执行时间总和进行排序,可以看到是在process_item和download,upload_image这些主流程函数的执行时间比较长,这一步是先把图片下载到本地,然后上传到静床,看来是下载这步从网络中read数据时出现了问题,进一步追踪代码。

使用py-spy解决scrapy卡死的问题方法

看下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卡死内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python中的自定义函数学习笔记
Sep 23 Python
在ironpython中利用装饰器执行SQL操作的例子
May 02 Python
Python调用SQLPlus来操作和解析Oracle数据库的方法
Apr 09 Python
Python 实现文件的全备份和差异备份详解
Dec 27 Python
wxpython实现图书管理系统
Mar 12 Python
Python 实现数据结构中的的栈队列
May 16 Python
在python 中split()使用多符号分割的例子
Jul 15 Python
Python之指数与E记法的区别详解
Nov 21 Python
关于Python中定制类的比较运算实例
Dec 19 Python
Python文件读写w+和r+区别解析
Mar 26 Python
Python基础类继承重写实现原理解析
Apr 03 Python
Python中np.random.randint()参数详解及用法实例
Sep 23 Python
详解python对象之间的交互
Sep 29 #Python
python PIL模块的基本使用
Sep 29 #Python
Python 如何实现数据库表结构同步
Sep 29 #Python
scrapy-redis分布式爬虫的搭建过程(理论篇)
Sep 29 #Python
python ssh 执行shell命令的示例
Sep 29 #Python
Scrapy基于scrapy_redis实现分布式爬虫部署的示例
Sep 29 #Python
浅析python 字典嵌套
Sep 29 #Python
You might like
PHP数据类型之整数类型、浮点数的介绍
2013/04/28 PHP
eaglephp使用微信api接口开发微信框架
2014/01/09 PHP
php实现递归与无限分类的方法
2015/02/16 PHP
PHP统计目录中文件以及目录中目录大小的方法
2016/01/09 PHP
php多进程应用场景实例详解
2019/07/22 PHP
PHP获取php,mysql,apche的版本信息及更多服务器信息
2021/03/09 PHP
javascript预览上传图片发现的问题的解决方法
2010/11/25 Javascript
url参数中有+、空格、=、%、&、#等特殊符号的问题解决
2013/05/15 Javascript
JQuery判断HTML元素是否存在的两种解决方法
2013/12/26 Javascript
javascript/jquery获取地址栏url参数的方法
2014/03/05 Javascript
Windows8下搭建Node.js开发环境教程
2014/09/03 Javascript
javascript瀑布流式图片懒加载实例解析与优化
2016/02/23 Javascript
jQuery 移动端拖拽(模块化开发,触摸事件,webpack)
2016/10/28 Javascript
AngularJS ng-template寄宿方式用法分析
2016/11/07 Javascript
AngularJS中$injector、$rootScope和$scope的概念和关联关系深入分析
2017/01/19 Javascript
详解vue-cli脚手架中webpack配置方法
2018/08/22 Javascript
vue组件开发之用户无限添加自定义填写表单的方法
2018/08/28 Javascript
JavaScript在web自动化测试中的作用示例详解
2019/08/25 Javascript
JavaScript实现Tab标签页切换的最简便方式(4种)
2020/06/28 Javascript
vue created钩子函数与mounted钩子函数的用法区别
2020/11/05 Javascript
pymongo给mongodb创建索引的简单实现方法
2015/05/06 Python
python动态参数用法实例分析
2015/05/25 Python
浅谈python装饰器探究与参数的领取
2017/12/01 Python
详解python string类型 bytes类型 bytearray类型
2017/12/16 Python
python中字符串变二维数组的实例讲解
2018/04/03 Python
python如何实现异步调用函数执行
2019/07/08 Python
python实现猜拳小游戏
2020/04/05 Python
维也纳通行证:Vienna PASS
2019/07/18 全球购物
Hotels.com泰国:酒店预订网站
2019/11/20 全球购物
澳大利亚香水在线商店:City Perfume
2020/09/02 全球购物
如何整合JQuery和Prototype
2014/01/31 面试题
公司部门司机岗位职责
2014/01/03 职场文书
四议两公开实施方案
2014/03/28 职场文书
社会体育专业大学生职业生涯规划书
2014/09/17 职场文书
意外伤害赔偿协议书范文
2014/09/23 职场文书
校本课程教学计划
2015/01/19 职场文书