热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

golang/python下载大文件时怎样避免oom

2019独角兽企业重金招聘Python工程师标准问题场景:高频系统中,agent会向ATS服务器发出刷新和预缓存的请求,这里的请求h

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

    问题场景:高频系统中,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 chunksf.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 = ewbreak}if nr != nw {err = ErrShortWritebreak}}if er != nil {if er != EOF {err = er}break}}return written, err
}


转:https://my.oschina.net/u/2950272/blog/1623116



推荐阅读
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
author-avatar
忧之灵_435
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有