你了解node多进程吗

面对单进程单线程对多核使用不足的问题,前人的经验是启动多进程即可。理想状态下每个进程各自利用一个CPU,以此实现多核CPU的利用。

所幸,Node提供了 child_process 模块,并且也提供了 child_process.fork() 函数供我们实现进程的复制。

如下所示:

var fork = require('child_process').fork;
var cpus = require('os').cpus();
for (var i = 0; i < cpus.length; i++) {fork('./worker.js');
}

这段代码将会根据当前机器上的CPU数量复制出对应Node进程数。

通过 fork() 复制的进程都是一个独立的进程,这个进程中有着独立而全新的V8实例。它需要至少30毫秒的启动时间和至少10 MB的内存。尽管Node提供了 fork() 供我们复制进程使每个CPU内核都使用上,但是依然要切记 fork() 进程是昂贵的。好在Node通过事件驱动的方式在单线程上解决了大并发的问题,这里启动多个进程只是为了充分将CPU资源利用起来,而不是为了解决并发问题。

在前端浏览器中,JavaScript主线程与UI渲染共用同一个线程。执行JavaScript的时候UI渲染是停滞的,渲染UI时,JavaScript是停滞的,两者互相阻塞。长时间执行JavaScript将会造成UI停顿不响应。

为了解决这个问题,HTML5提出了WebWorker API。WebWorker允许创建工作线程并在后台运行,使得一些阻塞较为严重的计算不影响主线程上的UI渲染。

node进程中怎么通信

通过 fork() 或者其他API,创建子进程之后,为了实现父子进程之间的通信,父进程与子进程之间将会创建IPC通道。通过IPC通道,父子进程之间才能通过 message 和 send() 传递消息。

node多进程一个端口可以被多个进程监听吗

如果让服务都监听到相同的端口,将会有什么样的结果?示例如下所示:

var http = require('http');
http.createServer(function (req, res) {res.writeHead(200, { 'Content-Type': 'text/plain' });res.end('Hello World\n');
}).listen(8888, '127.0.0.1');

第一次启动正常,第二次启动报错,只有一个工作进程能够监听到该端口上,其余的进程在监听的过程中都抛出了 EADDRINUSE 异常,这是端口被占用的情况,新的进程不能继续监听该端口了。这个问题破坏了我们将多个进程监听同一个端口的想法。要解决这个问题,通常的做法是让每个进程监听不同的端口,其中主进程监听主端口,主进程对外接收所有的网络请求,再将这些请求分别代理到不同的端口的进程上。

为了解决上述这样的问题,Node在版本v0.5.9引入了进程间发送句柄的功能。 send() 方法除了能通过IPC发送数据外,还能发送句柄,第二个可选参数就是句柄,如下所示:

child.send(message, [sendHandle])

那什么是句柄?句柄是一种可以用来标识资源的引用,它的内部包含了指向对象的文件描述符。比如句柄可以用来标识一个服务器端socket对象、一个客户端socket对象、一个UDP套接字、一个管道等。

发送句柄意味着什么?在前一个问题中,我们可以去掉代理这种方案,使主进程接收到socket请求后,将这个socket直接发送给工作进程,而不是重新与工作进程之间建立新的socket连接来转发数据。文件描述符浪费的问题可以通过这样的方式轻松解决。来看看我们的示例代码。

主进程代码如下所示:

// parent.js
var cp = require('child_process');
var child1 = cp.fork('child.js');
var child2 = cp.fork('child.js');
var server = require('net').createServer();
server.listen(1337, function () {child1.send('server', server);child2.send('server', server);// 关掉server.close();
});

子进程代码如下所示:

// child.js
var http = require('http');
var server = http.createServer(function (req, res) {res.writeHead(200, { 'Content-Type': 'text/plain' });res.end('handled by child, pid is ' + process.pid + '\n');
});
process.on('message', function (m, tcp) {if (m === 'server') {tcp.on('connection', function (socket) {server.emit('connection', socket);});}
});

这个示例中直接将一个TCP服务器发送给了子进程。多个进程可以监听到相同的端口而不引起 EADDRINUSE 异常。

Cluster模块

Node在v0.8版本时新增的cluster 模块就能解决。在v0.8版本之前,实现多进程架构必须通过 child_process 来实现,要创建单机Node集群,由于有这么多细节需要处理,对普通工程师而言是一件相对较难的工作,于是v0.8时直接引入了 cluster 模块,用以解决多核CPU的利用率问题,同时也提供了较完善的API,用以处理进程的健壮性问题。

对于文章开头提到的创建Node进程集群, cluster实现起来也是很轻松的事情,如下所示:

// cluster.js
var cluster = require('cluster');
cluster.setupMaster({exec: "worker.js"
});
var cpus = require('os').cpus();
for (var i = 0; i < cpus.length; i++) {cluster.fork();
}

事实上 cluster 模块就是 child_process 和 net 模块的组合应用。cluster 启动时,如同我们上文里的代码一样,它会在内部启动TCP服务器,在 cluster.fork() 子进程时,将这个TCP服务器端socket的文件描述符发送给工作进程。

在 cluster 内部隐式创建TCP服务器的方式对使用者来说十分透明,但也正是这种方式使得它无法如直接使用 child_process 那样灵活。

你了解node多进程吗相关推荐

  1. node 多进程 vs java_node多进程服务器

    node提供了四种方法来创建子进程,分别是child_process.exec(),child_process.execFile(), child_process.fork(),child_proce ...

  2. 《大前端进阶 Node.js》系列 多进程模型底层实现(字节跳动被问)

    前言 Coding 应当是一生的事业,而不仅仅是 30 岁的青春饭 本文已收录 Github https://github.com/ponkans/F2E,欢迎 Star,持续更新 字节跳动面试官问: ...

  3. 宝塔部署node项目_SFF一站式node服务管理平台实践

    导语 本文阐述了基于Serverless搭建一站式node服务管理平台过程中,在开发框架.日志.监控.部署等方面遇到的问题及技术方案. 背景 Serverless是一种无服务器架构,它的弹性伸缩,按需 ...

  4. vue仿今日头条_字节跳动今日头条前端面经(4轮技术面+hr面)

    笔者读大三,前端小白一枚,正在准备春招,人生第一次面试,投了头条前端,总共经历了四轮技术面试和一轮hr面,不多说,直接上题 一面 自我介绍,然后问了为什么学习前端 算法:实现36进制转换 简述http ...

  5. 01 【nodejs简介】

    01 [nodejs简介] 1.前言 Node 的重要性已经不言而喻,很多互联网公司都已经有大量的高性能系统运行在 Node 之上.Node 凭借其单线程.异步等举措实现了极高的性能基准.此外,目前最 ...

  6. 热乎乎的宇宙头条校招前端面经

    点击上方"程序员黑叔",选择"置顶或者星标" 你的关注意义重大! 作者:要加油啊 https://juejin.im/post/6844904088337907 ...

  7. 补充下3月面试题(好未来、腾讯音乐、小药药)

    补充一下落下的3月份的面试题,关于春季面经可以看我的上文  .从出师不利.面面具挂,到拿到阿里2个offer 以下是目前还记得的面试题,希望对一些人有用. 好未来 call apply 作用和区别 说 ...

  8. 业务痛点、个人成长以及未来发展的一些思考

    今天我们不讲技术,给大家换换口味 聊聊我个人对发掘业务痛点.个人成长以及未来发展的一些思考 本文索引 发掘业务痛点.个人成长和未来发展的关系 如何发掘业务痛点 业务压力大怎么兼顾个人成长 如何训练自己 ...

  9. 一些可以参考的文档集合7

    之前的文章集合: 一些可以参考文章集合1_xuejianxinokok的博客-CSDN博客 一些可以参考文章集合2_xuejianxinokok的博客-CSDN博客 一些可以参考的文档集合3_xuej ...

最新文章

  1. 如何挖掘系统的业务价值
  2. 用户吐槽:Azure DevOps CI 体验太差
  3. RateLimiter 的底层实现是啥?
  4. 企业实战之分布式锁方案一步步的演变历程!,Java数据库索引面试题
  5. nib、xib、storyboard(故事板)
  6. POJ1988 Cube Stacking
  7. social science and IP
  8. 整顿满月,如今现金贷生不如死
  9. 【转】通用sqlserver分页存储过程
  10. Mac安装redis与后台启动
  11. bigdecimal divide四舍五入_BigDecimal 四则运算
  12. 服务器(Windows镜像)自建git服务器超详细教程
  13. Linux操作系统安装教程
  14. 如何运用js制作简单的登录界面(html)
  15. 2020年9月中国编程语言排行榜
  16. Baby Sign Language
  17. 如何处理pagefile.sys占用太多C盘空间
  18. Command python setup.py egg_info failed with error code 1 in /private/var/folders/14/4hz051qx0wqd3
  19. java中retry的使用
  20. world 字体 选取高亮_Word2003选取文字的N种方法

热门文章

  1. 80% 的学校还在给新生上 C 语言,它们 OUT 了吗?
  2. 数字蝶变,离不开云原生“苍穹”
  3. 微信被指监听用户,腾讯回应;谷歌意外推送 Android 11 Beta 更新;Linux 5.7 发布 | 极客头条...
  4. 2020 年,程序员如何拥抱 5G ?
  5. 多种方式创建 Entity Framework Core 上下文
  6. 为什么别人年底购物,同学们年底考证?
  7. 双十一,不玩盖楼,直接大额降价!
  8. 山东到底有没有互联网?
  9. Python 3.8 新功能大揭秘
  10. 十年无果,Linux 开发者放弃 VMware 诉讼