下载文件时不是直接下载文件,所以不能直接使用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大了我就暂停生成 谢谢你们