下载文件时不是直接下载文件,所以不能直接使用express的sendfile方法,自己生成文件写到response里面,但是当文件很大的(如超过5G),生成速度过快导致内存泄漏,一般怎么解决比较好点,目前有如下两种思路: 1.生成一部分然后睡眠,从而控制生成速度 2.直接生成到服务器然后下载 网大神提供下思路
流式处理,边生成边下载?
类似于 createFileReadStream().pipe(res)
这样的
文件生成速度远大于网络传输速度,导致生出的大文件一时传不出去,占内存到被吃光光
建议:你要把生成和传输分开,具体实现,你的两个思路都可以,看你场景吧。
一般情况哈,生成都是cpu密集
吧,生成完了下载就偏I\O密集
了,所以拆开合理一点。倾向方案2
1的话,如果你能控制生成开关,可以自己实现一个stream:类似pipe,把背压事件和生成开关结合
几个Tips
:
- 生出的文件,用
Buffer
,不占v8
堆,保持node
主线程的处理速度 - 尽量升级你server端
linux
的版本,TCP层面
会有很多优化,拥塞窗口
SACK
啥的 socketio
和pipe
也许会帮你简化部分代码
PS:
(readable).pipe(writeable)
中的pipe
是通过backpressure
解决读写两端速度差异的, 你的问题不在这。
因为pipe
内发现writeable.write()
返回false
继而的readable.pause()
后,并没有阻止你继续生成文件吃内存。。
node有stream,stream是支持背压的,当流生成输出过快超过阀值是应当暂停生成。。按照stream写好你的流,直接pipe到res就可以。类似一楼,,文件读取时比较快,但是node就走做到了自动调节速度,内部就是他的这一套机制在做到这个
@soda-wy 我之前看过pipe,我去详细看看stream 谢谢
@AnzerWall 我监控heap然后heap大了我就暂停生成 谢谢你们