问题场景:高频系统中,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相关推荐

  1. Go下载第三方包、git下载包:常见问题汇总

    1.go get google.golang.org/grpc 提示网络不通,如下图: 解决方法:go get google.golang.org/grpc 解决办法汇总_年少~年的博客-CSDN博客 ...

  2. python批量下载网页文件-超简单超详细python小文件、大文件、批量下载教程

    按照不同的情况,python下载文件可以分为三种: 小文件下载 大文件下载 批量下载 python 小文件下载 流程:使用request.get请求链接,返回的内容放置到变量r中,然后将r写入到你想放 ...

  3. python flask 大文件 下载_python flask 建站之文件上传下载(一)

    公众号: 数据乐趣 如有建议和问题,敬请留言. 上一篇简单讲了一下Flask建站的大概流程,本篇举个Flask实例进行说明. 建站简介 实例功能是实现文件的上传和下载. 开发软件采用Pycharm,p ...

  4. python批量下载文件教程_超简单超详细python小文件、大文件、批量下载教程

    按照不同的情况,python下载文件可以分为三种: 小文件下载 大文件下载 批量下载 python 小文件下载 流程:使用request.get请求链接,返回的内容放置到变量r中,然后将r写入到你想放 ...

  5. python 浏览器下载文件_同样一个下载地址,用python爬虫爬取的种子文件大小为0,而用浏览器是可以正常下载下来的?...

    1.访问某个网页,用浏览器可以下载其中嵌入的种子文件,种子文件大小是正常的,用迅雷工具也可以正常下载,但是用python爬虫爬取,并且下载下来的数据大小为0? 2.这是我自己写的代码. url = ' ...

  6. python下载大文件-使用python通过FTP下载大文件

    对不起,如果我回答我自己的问题,但我找到了解决方案. 我尝试了ftputil没有成功,所以我尝试了很多方式,最后,这工作: def ftp_connect(path): link = FTP(host ...

  7. python 批量下载网页图片_手把手教你爬取天堂网1920*1080大图片(批量下载)——实战篇|python基础教程|python入门|python教程...

    https://www.xin3721.com/eschool/pythonxin3721/ /1 前言/ 上篇文章 手把手教你爬取天堂网1920*1080大图片(批量下载)--理论篇我们谈及了天堂网 ...

  8. 从零开始学python大数据与量化交易下载_GitHub - mignonwong/Python-100-Days-1: Python - 100天从新手到大师...

    Python - 100天从新手到大师 作者:骆昊 说明:从项目上线到获得8w+星标以来,一直收到反馈说基础部分(前15天的内容)对新手来说是比较困难的,建议有配套视频进行讲解.最近把基础部分的内容重 ...

  9. 从零开始学python大数据与量化交易下载_GitHub - zhaojie1126/Python-100-Days-1: Python - 100天从新手到大师...

    Python - 100天从新手到大师 作者:骆昊 说明:从项目上线到获得8w+星标以来,一直收到反馈说基础部分(前15天的内容)对新手来说是比较困难的,建议有配套视频进行讲解.最近把基础部分的内容重 ...

最新文章

  1. linux中的ln属性,linux 常用基础命令 ln 详细介绍
  2. cmt跟踪算法 matlab_“水上大疆”招聘——雷达算法工程师
  3. 在数组中查找一个数并输出所处位置
  4. 点击按钮的时候,切换搜索框的显示与隐藏(动画)
  5. 服务器无法显示大内存的处理办法
  6. Spring AOP本质(7)
  7. The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple
  8. Java工程师学习步骤
  9. 这是一个沙雕题III(坑题)
  10. html5的常用标签,HTML5常用标签
  11. 布局文件中出现的错误
  12. Windows 8 页面应用测试(2)
  13. OCR图像识别与汽车后市场
  14. java 课程设计题目_Java课程设计题目有哪些?Java课程设计题目汇总
  15. 《微机原理与应用》题库
  16. MHZ是计算机的什么单位,电脑mhz是什么意思
  17. cinta作业6:拉格朗日定理
  18. Mysql 解决 Your password has expired.
  19. 免费开源的几款Web服务器软件简介
  20. 概率论与数理统计——重复抽样与不重复抽样的判定

热门文章

  1. burpsuit学习--修改来源地址
  2. 一种另类的解决URL中文乱码问题--对中文进行加密、解密处理
  3. CSS3-transition,过渡实例
  4. 类型名称了解typename的双重意义
  5. 2.0 vue内置指令与自定义指令
  6. scrapy-redis源码抛析
  7. nefu 628 Garden visiting
  8. linux系统中用户切换
  9. sql server image字段的转换
  10. python 读取文件读出来是什么格式-深入学习python解析并读取PDF文件内容的方法...