使用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 28 Python
Django中针对基于类的视图添加csrf_exempt实例代码
Feb 11 Python
Python使用pymongo模块操作MongoDB的方法示例
Jul 20 Python
对python中if语句的真假判断实例详解
Feb 18 Python
python对象与json相互转换的方法
May 07 Python
Python3.0 实现决策树算法的流程
Aug 08 Python
python模块hashlib(加密服务)知识点讲解
Nov 25 Python
python实现五子棋游戏(pygame版)
Jan 19 Python
python+opencv实现移动侦测(帧差法)
Mar 20 Python
Python 中的函数装饰器和闭包详解
Feb 06 Python
Django项目如何正确配置日志(logging)
Apr 29 Python
如何理解及使用Python闭包
Jun 01 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 全角转半角实现代码
2010/05/16 PHP
使用php shell命令合并图片的代码
2011/06/23 PHP
利用yahoo汇率接口实现实时汇率转换示例 汇率转换器
2014/01/14 PHP
php多任务程序实例解析
2014/07/19 PHP
Laravel 修改验证异常的响应格式实例代码详解
2020/05/25 PHP
JS实现仿QQ聊天窗口抖动特效
2015/05/10 Javascript
AngularJS基础 ng-href 指令用法
2016/08/01 Javascript
深入理解JS继承和原型链的问题
2016/12/17 Javascript
js面向对象编程总结
2017/02/16 Javascript
jQuery实现简单的滑动导航代码(移动端)
2017/05/22 jQuery
Angular 2 利用Router事件和Title实现动态页面标题的方法
2017/08/23 Javascript
原生JS进行前后端同构
2018/04/22 Javascript
Vue-Cli项目优化操作的实现
2019/10/27 Javascript
解决Vue-cli无法编译es6的问题
2020/10/30 Javascript
MySQL中表的复制以及大型数据表的备份教程
2015/11/25 Python
Python中进程和线程的区别详解
2017/10/29 Python
python检测主机的连通性并记录到文件的实例
2018/06/21 Python
Python正则匹配判断手机号是否合法的方法
2020/12/09 Python
浅谈Python反射 & 单例模式
2019/03/21 Python
Python 闭包,函数分隔作用域,nonlocal声明非局部变量操作示例
2019/10/14 Python
浅谈python元素如何去重,去重后如何保持原来元素的顺序不变
2020/02/28 Python
Python新手如何理解循环加载模块
2020/05/29 Python
Django实现任意文件上传(最简单的方法)
2020/06/03 Python
Python如何避免文件同名产生覆盖
2020/06/09 Python
pytorch使用horovod多gpu训练的实现
2020/09/09 Python
html5+css3之动画在webapp中的应用
2014/11/21 HTML / CSS
荷兰网上买鞋:MooieSchoenen.nl
2017/09/12 全球购物
车队司机自我鉴定
2014/03/02 职场文书
企业授权委托书范本
2014/04/02 职场文书
公司股权转让协议书
2014/04/12 职场文书
机关干部三严三实心得体会
2014/10/13 职场文书
2014年残疾人工作总结
2014/12/06 职场文书
企业转让协议书(范文2篇)
2019/08/15 职场文书
Redis性能监控的实现
2021/07/09 Redis
「玫瑰之王的葬礼」舞台剧主视觉图公开
2022/03/21 日漫
JavaScript架构localStorage特殊场景下二次封装操作
2022/06/21 Javascript