我有两个基于Axios的函数-downloadContent
和uploadContent
downloadContent
函数以流的形式返回数据,uploadContent
函数使用流上传数据。
这个想法本质上是在两个后端之间传输数据。但由于一些文件可能有点大(5- 10 GB+),我不想下载文件在内存中,然后上传它。
但这正是我在下面的方法/代码中观察到的--进程内存使用量不断增加,直到达到文件大小(ish)。
async function downloadContent(downloadUrl) {
return await axios
.get(downloadUrl, {
responseType: "stream",
})
.then((r) => ({
file: r.data,
someOtherProps: {},
}));
}
async function uploadContent() {
const download = await downloadContent("download/url");
return await axios.post("upload/url", download.file, {
headers: {
"Content-Type": "specific-content-type",
},
});
}
await uploadContent();
是我做错了什么吗?
一般来说,我如何在两台服务器之间实现流式传输,以最大限度地减少Axios的内存占用?
1条答案
按热度按时间ztigrdn81#
流可能正在内存中缓冲,这就是您观察到内存使用量增加的原因。
在原始代码中,有
downloadContent
函数,它以流的形式获取数据并返回。但是,当您调用uploadContent
函数时,您将流直接传递到Axiospost
方法中。默认情况下,Axios库在发出HTTP请求之前缓冲整个输入。当您将流作为数据参数(
download.file
)直接传递给axios.post
方法时,Axios会等待整个流被消耗(在内存中缓冲),然后才真正发出HTTP请求。这是因为Axios设计用于浏览器和Node.js,以及浏览器环境streams cannot be sent as request data directly。
因此,Axios在内存中缓冲流,以确保跨环境的兼容性。这就是导致大文件占用大量内存的原因。
另外,您可以在将请求数据发送到服务器之前对其进行转换。同样,完整请求被缓冲在存储器中。
若要避免在内存中缓冲整个文件,可以将流用作管道,以便在下载文件时上载文件。这样,您实际上是在传递数据,而不是保留它。
由于Axios不支持用作可写流,因此不能使用
pipe
方法将数据直接导入axios.post
。相反,您应该将可读流作为数据参数传递给
axios.post
,这与您最初所做的类似,但要确保流得到正确处理。此代码将内容作为流下载,然后将其作为流上传。关键是我们将可读流作为数据参数传递给
axios.post
。这应该在Node.js环境中工作。