9.1 服务模型的变迁

9.1.1 石器时代:同步

9.1.2 青铜时代:复制进程

9.1.3 白银时代:多线程

9.1.4 黄金时代:事件驱动

9.2 多进程架构

node提供了child_process模块,我们再将经典的示例代码存为worker.js文件,如下:

let http=require('http');
http.createServer(function (req,res) {res.writeHead(200,{'Content-Type':"text/plain"});res.end('hello world')
}).listen(Math.round((1+Math.random())*1000),'127.0.0.1');

将以下代码保存为master.js,并通过node master.js 启动它:

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

在*nix的系统下通过ps aux|grep worker.js查看进程数量。
这就是master-worker模式,又称主从模式。

fork复制的进程都是独立的,这个进程有着独立而全新的V8实例。fork进程是昂贵的。

9.2.1 创建子进程

新版的node里面子进程也有同步子进程和异步子进程了,这里指的是异步子进程
- spawn():启动一个子进程
- exec():启动一个子进程,与spawn的不同是他有一个回调函数
- execFile():启动一个子进程来执行可执行文件
- fork():与spawn类似,不同点在于他创建node子进程只需要指定js文件即可

spawn与exec、execFile的不同是,后两者创建时可以指定timeout属性设置超时时间,时间到之后可以杀死子进程。
exec与execFile不同的是,exec适合执行已有的命令,execFile适合执行文件。

let cp=require('child_process');
cp.spawn('node',['worker.js']);//没有回调函数
cp.exec('node worker.js',function (err,stdout,stderr) {});
cp.execFile('worker.js',function (err,stdout,stderr) {});
cp.fork('./worker.js');

9.2.2 进程间通信

parent.js:

let cp=require('child_process');
let n=cp.fork(__dirname+ './sub.js');
n.on('message',function (m) {});
n.send({hello:'world'});

sub.js:

process.on('message', function (m) {console.log('child got message', m);
});
process.send({foo: 'bar'});

进程间通信原理

IPC,Inter-Process Communication,即进程间通信。Node实现IPC通道的是管道(pipe)技术。表现在应用层的进程间通信只有简单的message事件和send方法,十分简洁和消息化。

IPC 通道是用命名管道或Domain Socket创建的,与网络socket的行为类似,属于双向通信。在node中,IPC通道被抽象为stream对象,在调用send时发送消息(类似与write()),接收到的消息会通过message事件(类似与data)触发给应用层。

只有启动的子进程是node进程时,子进程才会根据环境变量去连接IPC通道,对于其他类型的子进程则无法实现进程间通信,除非其他进程也按照约定去连接这个已经创建好的IPC通道。

9.2.3 句柄传递

2.端口共同监听
node底层对每个端口监听都设置了SO_REUSEADDR选项,含义是不同的进程可以就相同的网卡和端口进行监听,这个服务器端套接字可以被不同的进程服用。
由于独立启动的进程相互之间不知道文件描述符,所以监听相同端口时会失败。但对于发送的句柄还原出来的服务而言,他们的文件描述符是相同的,所以不会引起异常。
多个原因监听相同的端口,文件描述符同一时间只能被某个进程所有。换言之就是网络请求向服务器发送时,只有一个幸运的进程能够抢到连接,也就是说只有他能为这个请求进行服务。这些进程服务是抢占式的。

9.3 集群稳定之路

9.4 cluster模块

const cluster = require('cluster');
cluster.setupMaster({exec: 'worker.js',args: ['--use', 'https'],silent: true
});
cluster.fork(); // https worker
cluster.setupMaster({exec: 'worker.js',args: ['--use', 'http']
});
cluster.fork(); // http worker

就官方文档而言,他更喜欢如下形式:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;if (cluster.isMaster) {console.log(`主进程 ${process.pid} 正在运行`);// 衍生工作进程。for (let i = 0; i < numCPUs; i++) {cluster.fork();}cluster.on('exit', (worker, code, signal) => {console.log(`工作进程 ${worker.process.pid} 已退出`);});
} else {// 工作进程可以共享任何 TCP 连接。// 在本例子中,共享的是一个 HTTP 服务器。http.createServer((req, res) => {res.writeHead(200);res.end('你好世界\n');}).listen(8000);console.log(`工作进程 ${process.pid} 已启动`);
}

我建议用cluster.setupmaster()这个API,将主进程和工作进程从代码完全剥离。

9.4.1 cluster工作原理

cluster模块就是child_process和net模块的组合应用。cluster启动时,他会在内部启动tcp服务器,在cluster.fork()子进程时,将这个tcp服务器端socket的文件描述符发送给工作进程。如果进程是通过cluster.fork()复制出来的,那么他的环境变量里面就存在NODE_UNIQUE_ID,如果工作进程中存在listen()侦听网络端口的调用,他将拿到该文件描述符,通过SO_REUSEADDR进行端口重用,从而实现多个子进程共享端口。

深入浅出node.js第9章玩转进程摘录相关推荐

  1. 一个月时间整理《深入浅出Node.js》

    今天终于把朴灵老师写的<深入浅出Node.js>给学习完了, 这本书不是一本简单的Node入门书籍,它没有停留在Node介绍或者框架.库的使用层面上,而是从不同的视角来揭示Node自己内在 ...

  2. 深入浅出Node.js(一):什么是Node.js(转贴)

    以下内容转自:http://www.infoq.com/cn/articles/what-is-nodejs/ 作者:崔康 [编者按]:Node.js从2009年诞生至今,已经发展了两年有余,其成长的 ...

  3. 深入浅出Node.js(上)

    (一):什么是Node.js Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟 ...

  4. 深入浅出Node.js

    深入浅出Node.js(一):什么是Node.js [编者按]:Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node. ...

  5. (转)深入浅出Node.js(一):什么是Node.js

    原文地址:http://www.infoq.com/cn/articles/what-is-nodejs [编者按]:Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在 ...

  6. 【深入浅出Node.js系列十一】Node.js开发框架Express4.x

    为什么80%的码农都做不了架构师?>>>    #0 系列目录# 深入浅出Node.js系列 [深入浅出Node.js系列一]什么是Node.js [深入浅出Node.js系列二]N ...

  7. 转载:Node.js入门系列——《深入浅出Node.js》

    作者:田永强 日期:2011-12-02 完整版 前言: Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS ...

  8. 深入浅出Node.js游戏服务器开发--分布式聊天服务器搭建

    From: http://www.infoq.com/cn/articles/game-server-development-2?utm_source=infoq&utm_medium=rel ...

  9. 深入浅出Node.js(八):Connect模块解析(之二)静态文件中间件

    为什么80%的码农都做不了架构师?>>>    上一篇专栏简单介绍了Connect模块的基本架构,它的执行模型十分简单,中间件机制也使得它十分易于扩展,具备良好的可伸缩性.在Conn ...

  10. 深入浅出Node.js(一):什么是Node.js

    专栏的第一篇文章<什么是Node.js>尝试从各个角度来阐述Node.js的基本概念.发展历史.优势等,对该领域不熟悉的开发人员可以通过本文了解Node.js的一些基础知识. 从名字说起 ...

最新文章

  1. js对象数组(JSON) 根据某个共同字段 分组
  2. MATLAB可视化实战系列(四十二)-图像特征提取-使用低秩 SVD 进行图像压缩实例
  3. SAP 系统中图标代码的查找
  4. 100%你没见过的魔兽表情包,拿去!再扯情怀已俗!
  5. java实现红包要多少钱_Java实现发红包功能
  6. 【JAVA 第三章 流程控制语句】课后习题 找零钱
  7. Jenkins pipeline+Maven+Gitlab
  8. 【聚会】2014圣诞北京版主聚餐-淘虾记“光辉岁月”版
  9. 韦东山嵌入式Linux三大学习路线
  10. Eclipse代码/目录虚线对齐设置
  11. 【转】redis利用姿势收集
  12. 乐高魔方机器人编程及图纸_LEGO 机器人魔方还原基本方法与过程
  13. CUDA安装教程及调试:本机win10+vs2013+NVIDIA GeForce GTX 1050Ti
  14. 社区购物、社区买菜小程序源码
  15. 考研英国文学复习要点
  16. 18.通过按键切换LED颜色
  17. SQLServer Job 邮件发送
  18. go语言中flag库使用
  19. N-puzzle-Problem
  20. (二)DDL操作数据库

热门文章

  1. MapReduce模型、大数据与数据挖掘、云计算的关系
  2. SPI接口的多芯片扩展8串口方案的实现
  3. cdr 表格自动填充文字_cdr中看似简单的小工具,你真的会用吗?
  4. hadoop 常用命令
  5. java实现界面化,java实现图形化界面
  6. 微信小程序里实现自定义日期控件
  7. 【技巧】vscode快速生成html结构
  8. golang中的URL 的编码和解码(转)
  9. 黑鲨重装计算机安装无法继续,图解黑鲨装机大师装机失败无法开机怎么办?
  10. 美国7月份CPI价格指数上涨8.5%不及市场预期 美联储加息的压力减轻