javascript - 事件侦听器是否在 Node.js 中保留在内存中?
问题描述
在 Samer Buna 的以下文章中...
https://medium.freecodecamp.org/node-js-child-processes-everything-you-need-to-know-e69498fe970a)
他谈到了child_process.fork
在 Node.js 中的使用。在他的示例中(靠近底部),他有一个简单的 HTTP 服务器来侦听请求事件,当事件发生时,他使用child_process.fork
创建进程来执行长计算,然后在完成后将消息发送回父级。为了返回子进程的结果,他注册了一个事件监听器,监听来自子进程的消息,然后返回响应。很直接。
一旦父进程收到子进程的消息并发送响应,compute.on
事件监听器会发生什么?它是否存在于内存中(事件循环)?如果该示例处理了 100 个请求,即使请求已返回,是否还会有 100 个事件侦听器在监听?
计算.js
const longComputation = () => {
let sum = 0;
for (let i = 0; i < 1e9; i++) {
sum += i;
};
return sum;
};
process.on('message', (msg) => {
const sum = longComputation();
process.send(sum);
});
服务器.js
const http = require('http');
const { fork } = require('child_process');
const server = http.createServer();
server.on('request', (req, res) => {
if (req.url === '/compute') {
const compute = fork('compute.js');
compute.send('start');
compute.on('message', sum => {
res.end(`Sum is ${sum}`);
});
} else {
res.end('Ok')
}
});
server.listen(3000);
解决方案
事件侦听器会一直保存在内存中,直到它们所附加的 EventEmitter 被销毁。
对于您的代码,子进程及其事件侦听器永远不会被丢弃。当收到请求时,每次都会创建一个全新的子进程。请求回调完成后,对分叉进程的引用被垃圾回收,但子进程本身仍在后台运行,造成大量僵尸进程和内存泄漏。虽然,您的事件侦听器将持续存在。
更好的架构可能是在应用程序启动时启动一个子进程池(或者,如果您的负载较轻,则只启动一个进程),然后根据需要使用这些子进程来处理请求。
推荐阅读
- c# - 清除文本框值
- vb.net - 完成执行任务“RdlCompile”——Visual Studio 2015 中的 FAILED 错误
- php - Laravel 5.6 http://127.0.0.1:8000/ 重定向到 https://127.0.0.1:8000/login (https)
- android - 如何在将用户带到下一个选项卡之前处理 TabLayout 单击?
- git - Git 复制文件到服务器
- python - 将列表数字相乘并打印总数(聚合)
- python - PyCharm 在 2018.3.2 中不会自动完成 Django“模型”
- ansible - Ansible:如何选择导入剧本?
- bash - 从 Curl 请求中获取状态码和响应正文
- c++ - 重新排序矢量数据的有效方法(解释为 3D 数组)