Node.js 中流式响应的背压处理:从一次文件下载服务超时说起
线上有一个文件导出服务,用户点击下载后,后端从数据库拉取数据并实时生成 CSV,通过 HTTP 流式返回。高峰期出现了部分请求卡死、内存飙升甚至进程被 OOM killer 杀掉的情况。排查后发现,代码里把数据库查询结果直接 pipe 到响应流,但没有正确监听 drain 事件,也没有处理 writable 的背压信号。当客户端网络较慢时,响应流的内部缓冲区持续堆积,而生产者(数据库游标)仍在全速读取,最终内存失控。这篇文章从流的基本原理出发,梳理 readable 与 writable 的背压机制,结合真实可运行的代码说明如何在一个导出接口里正确实现背压控制,并给出排查这类问题的实用手段。