python下载大文件-golang/python 下载大文件时怎样避免oom
问题场景:高频系统中,agent 会向ATS 服务器发出刷新和预缓存的请求,这里的请求head 里面有GET ,PURGE等,因为一般的预缓存都是小文件,但是某天,突然服务器oom。。。罪魁祸首发现是并发GET 大文件将服务器打死了。第一个版本是python 的,第二个版本是golang 实现的, 这里记录下两种语言的 下载大文件的实现方式。
该文章后续仍在不断的更新修改中, 请移步到原文地址http://dmwan.cc
第一种是python,使用的是request 库, 使用流式读取的方式,写到空设备中去。
res = self.session.request(method, url, data=body, headers=header, timeout=timeout, proxies=proxies, stream=True)
with open("/dev/null", 'wb') as f:
for chunk in res.iter_content(chunk_size=1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
f.flush()
第二种方式,对于golang ,使用io.Copy(), 将response copy 到空设备中。
func downLoadFile(url string)(len int, err error){
//err write /dev/null: bad file descriptor#
out, err := os.OpenFile("/dev/null", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
defer out.Close()
resp, err := http.Get(url)
defer resp.Body.Close()
n, err := io.Copy(out, resp.Body)
return n, err
}
使用这种方式为什么不会出现oom 的情况?因为两个原因,第一个, resp.Body 只是个reader 并没有发生真实的读取操作,第二个是io.copy 这个函数设置了缓冲区大小限制为3m,不会一次全部读取到内存中,下面是标准库的源码:
func Copy(dst Writer, src Reader) (written int64, err error) {
return copyBuffer(dst, src, nil)
}
// copyBuffer is the actual implementation of Copy and CopyBuffer.
// if buf is nil, one is allocated.
func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
// If the reader has a WriteTo method, use it to do the copy.
// Avoids an allocation and a copy.
if wt, ok := src.(WriterTo); ok {
return wt.WriteTo(dst)
}
// Similarly, if the writer has a ReadFrom method, use it to do the copy.
if rt, ok := dst.(ReaderFrom); ok {
return rt.ReadFrom(src)
}
if buf == nil {
buf = make([]byte, 32*1024) //这一步可以控制每次缓冲区迭代的大小,默认大小是3m
}
for {
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if nw > 0 {
written += int64(nw)
}
if ew != nil {
err = ew
break
}
if nr != nw {
err = ErrShortWrite
break
}
}
if er != nil {
if er != EOF {
err = er
}
break
}
}
return written, err
}
python下载大文件-golang/python 下载大文件时怎样避免oom相关推荐
- Go下载第三方包、git下载包:常见问题汇总
1.go get google.golang.org/grpc 提示网络不通,如下图: 解决方法:go get google.golang.org/grpc 解决办法汇总_年少~年的博客-CSDN博客 ...
- python批量下载网页文件-超简单超详细python小文件、大文件、批量下载教程
按照不同的情况,python下载文件可以分为三种: 小文件下载 大文件下载 批量下载 python 小文件下载 流程:使用request.get请求链接,返回的内容放置到变量r中,然后将r写入到你想放 ...
- python flask 大文件 下载_python flask 建站之文件上传下载(一)
公众号: 数据乐趣 如有建议和问题,敬请留言. 上一篇简单讲了一下Flask建站的大概流程,本篇举个Flask实例进行说明. 建站简介 实例功能是实现文件的上传和下载. 开发软件采用Pycharm,p ...
- python批量下载文件教程_超简单超详细python小文件、大文件、批量下载教程
按照不同的情况,python下载文件可以分为三种: 小文件下载 大文件下载 批量下载 python 小文件下载 流程:使用request.get请求链接,返回的内容放置到变量r中,然后将r写入到你想放 ...
- python 浏览器下载文件_同样一个下载地址,用python爬虫爬取的种子文件大小为0,而用浏览器是可以正常下载下来的?...
1.访问某个网页,用浏览器可以下载其中嵌入的种子文件,种子文件大小是正常的,用迅雷工具也可以正常下载,但是用python爬虫爬取,并且下载下来的数据大小为0? 2.这是我自己写的代码. url = ' ...
- python下载大文件-使用python通过FTP下载大文件
对不起,如果我回答我自己的问题,但我找到了解决方案. 我尝试了ftputil没有成功,所以我尝试了很多方式,最后,这工作: def ftp_connect(path): link = FTP(host ...
- python 批量下载网页图片_手把手教你爬取天堂网1920*1080大图片(批量下载)——实战篇|python基础教程|python入门|python教程...
https://www.xin3721.com/eschool/pythonxin3721/ /1 前言/ 上篇文章 手把手教你爬取天堂网1920*1080大图片(批量下载)--理论篇我们谈及了天堂网 ...
- 从零开始学python大数据与量化交易下载_GitHub - mignonwong/Python-100-Days-1: Python - 100天从新手到大师...
Python - 100天从新手到大师 作者:骆昊 说明:从项目上线到获得8w+星标以来,一直收到反馈说基础部分(前15天的内容)对新手来说是比较困难的,建议有配套视频进行讲解.最近把基础部分的内容重 ...
- 从零开始学python大数据与量化交易下载_GitHub - zhaojie1126/Python-100-Days-1: Python - 100天从新手到大师...
Python - 100天从新手到大师 作者:骆昊 说明:从项目上线到获得8w+星标以来,一直收到反馈说基础部分(前15天的内容)对新手来说是比较困难的,建议有配套视频进行讲解.最近把基础部分的内容重 ...
最新文章
- linux中的ln属性,linux 常用基础命令 ln 详细介绍
- cmt跟踪算法 matlab_“水上大疆”招聘——雷达算法工程师
- 在数组中查找一个数并输出所处位置
- 点击按钮的时候,切换搜索框的显示与隐藏(动画)
- 服务器无法显示大内存的处理办法
- Spring AOP本质(7)
- The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple
- Java工程师学习步骤
- 这是一个沙雕题III(坑题)
- html5的常用标签,HTML5常用标签
- 布局文件中出现的错误
- Windows 8 页面应用测试(2)
- OCR图像识别与汽车后市场
- java 课程设计题目_Java课程设计题目有哪些?Java课程设计题目汇总
- 《微机原理与应用》题库
- MHZ是计算机的什么单位,电脑mhz是什么意思
- cinta作业6:拉格朗日定理
- Mysql 解决 Your password has expired.
- 免费开源的几款Web服务器软件简介
- 概率论与数理统计——重复抽样与不重复抽样的判定