使用 Node.js Stream API 减少服务器端内存消耗的一个具体例子

简介: 使用 Node.js Stream API 减少服务器端内存消耗的一个具体例子

让我们看一个示例,展示在内存消耗方面,采用流的编程思路带来的巨大优越性。


我们先创建一个大文件:


const fs = require('fs');
const file = fs.createWriteStream('./big.file');
for(let i=0; i<= 1e6; i++) {
  file.write('this is a big file.\n');
}
file.end();



fs 模块可用于使用流接口读取和写入文件。 在上面的示例中,我们通过一个循环写入 100 万行的可写流,向该 big.file 写入数据。


运行上面的代码会生成一个大约 400 MB 的文件。


这是一个简单的 Node Web 服务器,旨在专门为 big.file 提供服务:


const fs = require('fs');
const server = require('http').createServer();
server.on('request', (req, res) => {
  fs.readFile('./big.file', (err, data) => {
    if (err) throw err;
    res.end(data);
  });
});
server.listen(8000);


启动该服务器,其消耗的初始内存为 8 MB 左右。



使用浏览器访问服务器之后,内存消耗跃升至 434.8 MB。


我们基本上将整个 big.file 内容放在内存中,然后再将其写入响应对象。 这是非常低效的。


HTTP 响应对象(上面代码中的 res)也是一个可写流。 这意味着如果我们有一个表示 big.file 内容的可读流,我们可以将这两个相互连接起来,并在不消耗约 400 MB 内存的情况下获得几乎相同的结果。


Node 的 fs 模块可以使用 createReadStream 方法为我们提供任何文件的可读流。 我们可以将其通过管道传递给响应对象:


const fs = require('fs');
const server = require('http').createServer();
server.on('request', (req, res) => {
  const src = fs.createReadStream('./big.file');
  src.pipe(res);
});
server.listen(8000);


我们现在访问上述重新实现过的服务器,发现内存消耗量大大降低了。


这是因为,当客户端请求该大文件时,我们一次将其流式传输一个块,这意味着我们根本不会将其整个的庞大文件内容缓冲在内存中。 内存使用量增加了大约 25 MB,仅此而已。


我们可以把测试场景设计得更极端一些:用 500 万行而不是 100 万行重新生成 big.file,这将使文件超过 2 GB,这实际上大于 Node.js 中的默认缓冲区限制。


如果尝试使用 fs.readFile 提供该文件,则默认情况下会出现 out of memory 的错误。


但是使用 fs.createReadStream,将 2 GB 的数据流式传输到请求者完全没有问题,而且最重要的是,进程内存使用情况大致相同。


相关文章
|
1月前
|
API
egg.js 24.2写第一个api接口
egg.js 24.2写第一个api接口
71 0
|
3月前
|
JavaScript Ubuntu
百度搜索:蓝易云【Ubuntu搭建Nodejs服务器】
请注意,以上步骤仅是简单的示例,实际上,你可以根据需要配置更多Node.js服务器设置和添加更多功能。
37 2
|
3月前
|
JavaScript 前端开发 API
释放 Node.js 的力量:服务器端 JavaScript 综合指南
释放 Node.js 的力量:服务器端 JavaScript 综合指南
31 0
|
18天前
|
开发框架 JavaScript 中间件
node+express搭建服务器环境
node+express搭建服务器环境
node+express搭建服务器环境
|
2月前
|
消息中间件 Web App开发 JavaScript
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
77 0
|
2月前
|
Web App开发 JavaScript NoSQL
深入浅出:构建基于Node.js的RESTful API
在当今快速发展的互联网时代,RESTful API已成为前后端分离架构中不可或缺的一部分。本文旨在为初学者和中级开发人员提供一个清晰、简洁的指南,详细介绍如何使用Node.js构建一个高效、可维护的RESTful API。通过结合实际案例,本文将从API设计理念出发,深入讲解如何利用Express框架及MongoDB数据库实现API的增删改查功能,同时探讨如何通过JWT进行安全认证,确保数据传输的安全性。此外,文章还将简要介绍如何使用Swagger生成API文档,使得API的测试和维护更加便捷。无论你是希望提升现有项目的API设计,还是想从零开始构建一个新项目,本文都将为你提供一条清晰的道路
|
9天前
|
JavaScript 前端开发 UED
Vue工具和生态系统: Vue.js和服务器端渲染(SSR)有关系吗?请解释。
Vue.js是一个渐进式JavaScript框架,常用于开发单页面应用,但其首屏加载较慢影响用户体验和SEO。为解决此问题,Vue.js支持服务器端渲染(SSR),在服务器预生成HTML,加快首屏速度。Vue.js的SSR可手动实现或借助如Nuxt.js的第三方库简化流程。Nuxt.js是基于Vue.js的服务器端渲染框架,整合核心库并提供额外功能,帮助构建高效的应用,改善用户体验。
12 0
|
15天前
|
JavaScript 算法 网络协议
【Node系列】node中的流(Stream)
Node.js 中的流(Stream)是一种处理数据的方式,它允许你以流的方式处理数据,而不是一次性加载整个数据集。这种方式对于处理大量数据非常有用,因为它可以减少内存的使用并提高性能。
26 4
|
1月前
|
监控 JavaScript 安全
监控内网电脑软件设计与实现:基于Node.js的服务器端架构分析
在当今信息技术高度发达的时代,监控内网电脑的需求日益增长。企业需要确保网络安全,个人用户也需要监控家庭网络以保护隐私和安全。本文将介绍一种基于Node.js的服务器端架构,用于设计和实现监控内网电脑软件。
104 0
|
1月前
|
Web App开发 JavaScript 前端开发
使用Node.js和Express构建RESTful API
使用Node.js和Express构建RESTful API
19 0