node进程间通信 (2)

cluster本质上也是通过child_process.fork创建子进程,他还能帮我们合理的管理进程。

const cluster = require('cluster'); // 判断是否为主进程 if (cluster.isMaster) { const cpuNum = require('os').cpus().length; for (let i = 0; i < cpuNum; ++i) { cluster.fork(); } cluster.on('online', (worker) => { console.log('Create worker-' + worker.process.pid); }); cluster.on('exit', (worker, code, signal) => { console.log( '[Master] worker ' + worker.process.pid + ' died with code:' + code + ', and' + signal ); cluster.fork(); // 重启子进程 }); } else { const net = require('net'); net.createServer() .on('connection', (socket) => { setTimeout(() => { socket.end('Request handled by worker-' + process.pid); }, 10); }) .listen(8989); }

细心地你可能发现多个子进程监听了同一个端口,这样不会EADDRIUNS吗?

其实不然,真正监听端口的是主进程,当前端请求到达时,会将句柄发送给某个子进程。

理解底层基础,助力上层应用

进程间通信(IPC)大概有这几种:

匿名管道

命名管道

信号量

消息队列

信号

共享内存

套接字

从技术上划分又可以划分成以下四种:

消息传递(管道,FIFO,消息队列)

同步(互斥量,条件变量,读写锁等)

共享内存(匿名的,命名的)

远程过程调用

文件描述符是什么?

在linux中一切皆文件,linux会给每个文件分配一个id,这个id就是文件描述符,指针也是文件描述符的一种。这个很好理解,不过我们可以再往深了说,一个进程启动后,会在内核空间(虚拟空间的一部分)创建一个PCB控制块,PCB内部有一个文件描述符表,记录着当前进程所有可用的文件描述符(即当前进程所有打开的文件)。系统出了维护文件描述符表外,还需要维护打开文件表(Open file table)和i-node表(i-node table)。

文件打开表(Open file table)包含文件偏移量,状态标志,i-node表指针等信息

i-node表(i-node table)包括文件类型,文件大小,时间戳,文件锁等信息

文件描述符不是一对一的,它可以:

同一进程的不同文件描述符指向同一文件

不同进程可以拥有相同的文件描述符(比如fork出的子进程拥有和父进程一样的文件描述符,或者不同进程打开同一文件)

不同进程的同一文件描述符也可以指向不同的文件

不同进程的不同文件描述符也可以指向同一个文件

上面提及了很多可以实现进程间通信的方式,那node进程间通信是以什么为基础的呢?

nodeIPC通过管道技术 加 事件循环方式进行通信,管道技术在windows下由命名管道实现,在*nix系统则由Unix Domain socket实现,提供给我们的是简单的message事件和send方法。

那管道是什么呢?

管道实际上是在内核中开辟一块缓冲区,它有一个读端一个写端,并传给用户程序两个文件描述符,一个指向读端,一个指向写端口,然后该缓存区存储不同进程间写入的内容,并供不同进程读取内容,进而达到通信的目的。

管道又分为匿名管道和命名管道,匿名管道常见于一个进程fork出子进程,只能亲缘进程通信,而命名管道可以让非亲缘进程进行通信。

node进程间通信

其实本质上来说进程间通信是利用内核管理一块内存,不同进程可以读写这块内容,进而可以互相通信,当然,说起来简单,做起来难。有兴趣的朋友可以自行研究。

进程保护

可以用cluster建立主从进程架构,主进程调度管理和分发任务给子进程,并在子进程挂掉或断开连接后重启。

pm2是对cluster的一种封装,提供了:

内奸负载均衡

后台运行

停机重载

具有Ubuntu、CentOS的启动脚本

停止不稳定的进程

控制台检测

有好的可视化界面

具体原理和细节以后有空再做分析。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgxpw.html