node多进程的创建与守护

2022-11-24 0 579

1. node的单缓存

民主化是两个具有很大分立功能的流程在两个统计数据K568的一次静态继续执行的过程,是作业控制系统进行天然分权和运维的两个分立基层单位,是应用流程运转的媒介。

缓存是流程继续执行中两个单个的顺序控制流,它存有于民主化之中,是比民主化更小的能分立运转的基本上基层单位。

早期在R5 CPU 的控制系统中,为的是实现虚拟化的运转,导入了民主化的基本上概念,不同的流程运转在统计数据与命令互相隔绝的民主化中,通过天数片Tiruvanamalai运维继续执行,虽然 CPU 天数片转换与继续执行很快,因此看起来像在同一个天数运转了数个流程。

虽然民主化转换时需要留存相关硬体当晚、民主化控制块等信息,因此控制系统开支较大。为的是不断提高控制系统林宏吉率,在同一个民主化继续执行时更充分的借助 CPU 资源,导入了缓存的基本上概念。缓存是作业控制系统运维继续执行的最轻基层单位,它们依附民主化中,共享资源同一个民主化中的天然资源,基本上不保有或者只保有小量控制系统天然资源,转换开支很小。

Node是如前所述V8发动机其内构筑的,决定了他与应用程序的机制很类似。

两个node民主化根本无法借助两个核,而且node根本无法运转在单缓存中,严苛意义上,node绝非真正的单缓存构架,即两个民主化内能有数个缓存,即使node自己还有很大的i/o缓存存有,那些I/O缓存由下层的libuv处理,但那些缓存对node开发人员而言是完成透明化的,只有在C++扩充TNUMBERV12V4会加进,这里他们就过滤下层的技术细节,专门探讨他们所要关注的。

node多进程的创建与守护
node的构架层次

单缓存的益处是:流程状态单个,在没多缓存的情况下,没锁、缓存并行问题,作业控制系统在运维时,也即使极少的语句的转换,能较好地提高CPU的使用量。然而R5单缓存也有相应的优点:

那个缓存读出来后整个流程就会读出来;无法充分借助多核天然资源
node多进程的创建与守护
两个CPU运转到死,其他的CPU在看着

2. node多民主化的建立

node提供更多child_process组件,那个组件中,提供更多了数个方法来建立子民主化。

const { spawn, exec, execFile, fork } = require(child_process);

这4个方法都能建立子民主化,不过使用方法还是稍微有点区别。他们以建立两个子民主化计算斐波那契数列数列为例,子民主化的文件(worker.js):

// worker.jsconst fib = (num) => { if (num === 1 || num === 2) { return num; } let a = 1, b = 2, sum = 0; for (let i = 3; i <= num; i++) { sum = a + b; a = b; b = sum; } return sum; } const num = Math.floor(Math.random() * 10) + 3; const result = fib(num); console.log(num, result, process.pid); // process.pid表示当前的民主化id

在master.js中如何调用那些方法建立子民主化呢?

命令使用方法解析spawnspawn(node, [worker.js])启动两个字民主化来继续执行命令execexec(node worker.js, (err, stdout, stderr) => {})启动两个子民主化来继续执行命令,有回调execFileexexFile(worker.js)启动两个子民主化来继续执行可继续执行的文件

(头部要添加#!/usr/bin/env node)forkfork(worker.js)与spawn类似,不过这里只需要自定js文件组件即可

以fork命令为例:

const { fork } = require(child_process); const cpus = require(os).cpus(); for(let i=0, len=cpus.length; i<len; i++) { fork(./worker.js); }

3. 多民主化之间的通信

node中民主化的通信主要在主从(子)民主化之间进行通信,子民主化之间无法直接通信,若要互相通信,则要通过主进程进行信息的转发。

主民主化和子民主化之间是通过IPC(Inter Process Communication,民主化间通信)进行通信的,IPC也是由下层的libuv根据不同的作业控制系统来实现的。

他们还是以计算斐波那契数列数列为例,在这里,他们用cpu个数减1个的民主化来进行计算,剩余的那两个用来输出结果。这就需要负责计算的子民主化,要把结果传给主民主化,再让主民主化传给输出进行,来进行输出。这里他们需要3个文件:

master.js:用来建立子民主化和子民主化间的通信;fib.js:计算斐波那契数列;log.js:输出斐波那契数列计算的结果;

主民主化:

// master.js const { fork } = require(child_process); const cpus = require(os).cpus(); const logWorker = fork(./log.js); for(let i=0, len=cpus.length1; i<len; i++) { const worker = fork(./fib.js); worker.send(Math.floor(Math.random()*10 + 4)); // 要计算的num worker.on(message, (data) => { // 计算后返回的结果 logWorker.send(data); // 将结果发送给输出民主化 }) }

计算民主化:

// fib.js const fib = (num) => { if (num===1 || num===2) { return num; } let a=1, b=2, sum=0; for(let i=3; i<num; i++) { sum = a + b; a = b; b = sum; } return sum; } process.on(message, num => { const result = fib(num); process.send(JSON.stringify({ num, result, pid: process.pid })) })

输出民主化:

process.on(message, data => { console.log(process.pid, data); })

当他们运转master时,就能看到各个子民主化计算的结果:

node多进程的创建与守护
多进程的斐波那契数列输出结果

第1个数字表示当前输出子民主化的编号,后面表示在各个子民主化计算的统计数据。

同理,他们在进行http服务日志记录时,也能采用类似的思路,数个子民主化承担http服务,剩下的子民主化来进行日志记录等操作。

当我想用子民主化建立服务器时,采用上面类似斐波那契数列的思路,将fib.js改为httpServer.js:

// httpServer.js const http = require(http); http.createServer((req, res) => { res.writeHead(200, { Content-Type: text/html }); res.end(Math.random()+); }).listen(8080); console.log(http server has started at 8080, pid: +process.pid);

结果却出现错误了,提示8080端口已经被占用了:

Error: listen EADDRINUSE: address already in use :::8080

这是即使:在TCP端socket套接字监听端口有两个文件描述符,每个民主化的文件描述符都不相同,监听相同端口时就会失败。

解决方案有两种:首先最简单的就是每个子民主化都使用不同的端口,主民主化将循环的标识给子民主化,子民主化通过那个标识来使用相关的端口(例如从8080+传入的标识作为当前民主化的端口号)。

第二种方案是,在主民主化进行端口的监听,然后将监听的套接字传给子民主化。

node多进程的创建与守护
将套接字socket发送给子民主化

主民主化:

// master.js const fork = require(child_process).fork; const net = require(net); const server = net.createServer(); const child1 = fork(./httpServer1.js); // randomconst child2 = fork(./httpServer2.js); // now server.listen(8080, () => { child1.send(server, server); child2.send(server, server); server.close(); })

httpServer1.js:

const http = require(http); const server = http.createServer((req, res) => { res.writeHead(200, { Content-Type: text/plain }); res.end(Math.random()+, at pid: + process.pid); }); process.on(message, (type, tcp) => { if (type===server) { tcp.on(connection, socket => { server.emit(connection, socket) }) } })

httpServer2.js:

const http = require(http); const server = http.createServer((req, res) => { res.writeHead(200, { Content-Type: text/plain }); res.end(Date.now()+, at pid: + process.pid); }); process.on(message, (type, tcp) => { if (type===server) { tcp.on(connection, socket => { server.emit(connection, socket) }) } })

他们的2个server,两个是输出随机数,两个是输出当前的天数戳,能发现这两个server都能正常的运转。同时,即使那些民主化服务是抢占式的,哪个民主化抢到连接,就哪个民主化处理请求。

他们也应当知道的是:

每个民主化之间的内存统计数据是不互通的,若他们在某一民主化中使用变量缓存了统计数据,另两个民主化是读取不到的。

4. 多民主化的守护者

刚才他们在第3部分建立的多民主化,解决了多核CPU借助率的问题,接下来要解决民主化稳定的问题。

每个子民主化退出时,都会触发exit事件,因此他们通过监听exit事件来获知有民主化退出了,这时,他们就能建立两个新的民主化来替代。

const fork = require(child_process).fork; const cpus = require(os).cpus(); const net = require(net); const server = net.createServer(); const createServer = () => { const worker = fork(./httpServer.js); worker.on(exit, () => { // 当有民主化退出时,则建立两个新的民主化 console.log(worker exit: + worker.pid); createServer(); }); worker.send(server, server); console.log(create worker: + worker.pid); } server.listen(8080, () => { for(let i=0, len=cpus.length; i<len; i++) { createServer(); } })

cluster组件

在多民主化守护者这块,node也推出了cluster组件,用来解决多核CPU的借助率问题。同时cluster中也提供更多了exit事件来监听子民主化的退出。

两个经典的案例:

const cluster = require(cluster); const http = require(http); const cpus = require(os).cpus(); if (cluster.isMaster) { console.log(`主民主化 ${process.pid} 正在运转`); // 衍生工作民主化。 for (let i = 0, len=cpus.length; i < len; i++) { cluster.fork(); } cluster.on(exit, (worker) => { console.log(`工作民主化 ${worker.process.pid} 已退出`); cluster.fork(); }); } else { http.createServer((req, res) => { res.writeHead(200); res.end(Math.random()+ , at pid: + process.pid); }).listen(8080); console.log(`工作民主化 ${process.pid} 已启动`); }

5. 总结

node虽然是单缓存运转的,但他们能通过建立数个子民主化,来充分借助多核CPU天然资源,通过能监听民主化的一些事件,来感知每个民主化的运转状态,来提高他们项目整体的稳定性。

我是蚊子,更多的内容还能关注我的公众号:蚊子的博客。

node多进程的创建与守护
蚊子的博客

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务