如何使用 Node.js Stream API 减少服务器端内存消耗?
摘要:让我们看一个示例,展示在内存消耗方面,采用流的编程思路带来的巨大优越性。
本文分享自华为云社区《使用 Node.js Stream API 减少服务器端内存消耗的一个具体例子》,作者:Jerry Wang 。
HTTP 响应对象(上面代码中的 res)也是一个可写流。这意味着如果我们有一个表示 big.file 内容的可读流,我们可以将这两个相互连接起来,并在不消耗约 400 MB 内存的情况下获得几乎相同的结果。 Node 的 fs 模块可以使用 createReadStream 方法为我们提供任何文件的可读流。 我们可以将其通过管道传递给响应对象。
让我们看一个示例,展示在内存消耗方面,采用流的编程思路带来的巨大优越性。
我们先创建一个大文件:
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 的数据流式传输到请求者完全没有问题,而且最重要的是,进程内存使用情况大致相同。
如何使用 Node.js Stream API 减少服务器端内存消耗?的更多相关文章
- Node.js 常用 API
Node.js v6.11.2 Documentation(官方文档) Buffer Prior to the introduction of TypedArray in ECMAScript 20 ...
- 9、Node.js Stream(流)
#########################################################################介绍Node.js Stream(流)Stream 是 ...
- 十个书写Node.js REST API的最佳实践(下)
收录待用,修改转载已取得腾讯云授权 5. 对你的Node.js REST API进行黑盒测试 测试你的REST API最好的方法之一就是把它们当成黑盒对待. 黑盒测试是一种测试方法,通过这种方法无需知 ...
- 编写 Node.js Rest API 的 10 个最佳实践
Node.js 除了用来编写 WEB 应用之外,还可以用来编写 API 服务,我们在本文中会介绍编写 Node.js Rest API 的最佳实践,包括如何命名路由.进行认证和测试等话题,内容摘要如下 ...
- AngularJS 授权 + Node.js REST api
作者好屌啊,我不懂的他全都懂. Authentication with AngularJS and a Node.js REST api 几个月前,我开始觉得 AngularJS 好像好牛逼的样子,于 ...
- Node.js RESTful API
什么是REST架构? REST表示代表性状态传输.REST是一种基于Web标准的架构,并使用HTTP协议. 它都是围绕着资源,其中每一个组件是资源和一个资源是由一个共同的接口使用HTTP的标准方法获得 ...
- Practical Node.js (2018版) 第8章:Building Node.js REST API Servers
Building Node.js REST API Servers with Express.js and Hapi Modern-day web developers use an architec ...
- 十个书写Node.js REST API的最佳实践(上)
收录待用,修改转载已取得腾讯云授权 原文:10 Best Practices for Writing Node.js REST APIs 我们会通过本文介绍下书写Node.js REST API的最佳 ...
- 使用Node.js原生API写一个web服务器
Node.js是JavaScript基础上发展起来的语言,所以前端开发者应该天生就会一点.一般我们会用它来做CLI工具或者Web服务器,做Web服务器也有很多成熟的框架,比如Express和Koa.但 ...
- 一个完整的Node.js RESTful API
前言 这篇文章算是对Building APIs with Node.js这本书的一个总结.用Node.js写接口对我来说是很有用的,比如在项目初始阶段,可以快速的模拟网络请求.正因为它用js写的,跟i ...
随机推荐
- DASCTF X CBCTF 2023|无畏者先行(Misc WP)
justpaint 1.题目信息 FLAG被我弄丢了>_<不过,JBN应该记得,或许你能从他那得到一些线索. 附件是压缩包有密码.. 2.解题方法 暴力破解压缩包,测试长度为6,选择所有数 ...
- Hello-FPGA CoaXPress 2.0 FPGA HOST IP Core PCIe Demo User Manual
目录 1 说明 4 2 设备连接 7 3 VIVADO FPGA工程 8 4 调试说明 9 图 1‑1 资料目录 4 图 1‑2 VIVADO工程目录结构 5 图 1‑3 VS软件工程目录 5 图 1 ...
- Nacos注册中心有几种调用方式?
Spring Cloud Alibaba Nacos 作为近几年最热门的注册中心和配置中心,也被国内无数公司所使用,今天我们就来看下 Nacos 作为注册中心时,调用它的接口有几种方式? 1.什么是注 ...
- JVM-Java虚拟机是怎么实现synchronized的?
1. JVM的锁优化 今天我介绍了 Java 虚拟机中 synchronized 关键字的实现,按照代价由高至低可分为重量级锁.轻量级锁和偏向锁三种. 重量级锁会阻塞.唤醒请求加锁的线程.它针对的是多 ...
- CSS 选择器权重计算与优先级
作者:WangMin 格言:努力做好自己喜欢的每一件事 在讲CSS 选择器权重计算与优先级之前,我们先来了解一下CSS是用来干什么的?CSS是用来通过添加样式使网页更加美观,也就是说CSS是利用选择器 ...
- Python 既是解释型语言,也是编译型语言
哈喽大家好,我是咸鱼 不知道有没有小伙伴跟我一样,刚开始学习 Python 的时候都听说过 Python 是一种解释型语言,因为它在运行的时候会逐行解释并执行,而 C++ 这种是编译型语言 不过我今天 ...
- 如何深度学习Python?
安装必要软件:首先需要安装Anaconda或Miniconda等科研计算环境,并创建虚拟环境以便管理不同项目所需库和版本.可以按照如下步骤进行操作: 下载并安装 Anaconda 或 Minicond ...
- 腾讯云与树莓派通信遇到的一些问题(树莓派无法ping通腾讯云指定端口)
采用的是socket通信,之前写过C的,这次需要用到python,参考的代码原链接如下:https://www.cnblogs.com/mosu/p/16072146.html. (1)首先开放一个端 ...
- Flask SocketIO 实现动态绘图
Flask-SocketIO 是基于 Flask 的一个扩展,用于简化在 Flask 应用中集成 WebSocket 功能.WebSocket 是一种在客户端和服务器之间实现实时双向通信的协议,常用于 ...
- 如何利用Excel/WPS表格制作智能成绩查询系统?
要利用Excel或WPS表格制作智能成绩查询系统,可以按照以下步骤进行: 1. 设计数据库结构:确定需要存储的学生信息和成绩数据,包括姓名.学号.科目.分数等字段. 2. 创建数据表:在Excel或W ...