node --- > [node接口阅读]cluster的使用

目标

  • 在主进程中完成以下事情:
  1. 每隔1秒钟输出,当前请求的数量
  2. 创建等同于CPU数量的进程
  3. 对每个进程施加一个处理函数,用于统计请求的数量
  • 在各个CPU的进程中完成以下事情
  1. 监听8000端口的请求,并返回最简单的信息
  2. 发送事件,以触发主进程中施加的事件处理函数

前置知识

  • process.pid
    在主进程cluster.isMaster中, process.id是主进程的id
    在工作进程(子进程)cluster.isWorker中,process.id是工作进程(子进程)的id

  • 获取cpu的数量
const numCPUs = require('os').cpus().length;

  • 判断一个进程是否为主进程
const cluster = require('cluster');
if(cluster.isMaster) { ... }

  • 创建一个新进程
const cluster = require('cluster');
const work = cluster.fork();

实现

const cluster=  require('cluster');
const http = require('http');

if(cluster.isMaster) {
	// 主进程
	let count = 0;
	// 每隔1秒钟,就输出当前的访问次数
	setInterval(()=>{
		console.log(`访问次数为: ${count}`)
	}, 1000);
	let numCPUs = require('os').cpus().length;
	for(let i =0 ; i < numCPUs ; i++) {
		cluster.fork();		// 创建等同于cpu核数的进程
	}
	for(let id in cluster.workers){
		cluster.workers[id].on('message', (msg) =>{
			if(msg.cmd && msg.cmd === 'notifyRequest') {
				count++;
			}
		})
	}
} else {
	// 子进程
	http.Server((req, res) => {
		if(req.url !== '/favicon.ico') {
			res.writeHead(200);
			res.end('Hi Marron');
			// 通知执行 cmd.notifyRequest 事件
			process.send({cmd: 'notifyRequest'});
		}
	}).listen(8000)
}

在这里插入图片描述


扩展

  • 由于node.js是单线程.很容易卡死而导致崩溃.如下
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx, next) =>{
	aaa();
	await next();
	ctx.body = 'marron';
});
app.listen(3000);
  • 说明会直接报错ReferenceError: aaa is not defined,会直接退出当前进程.
  • 思路: 可以在主进程中监听,一旦发现有进程死亡,就开启新的进程.

综上所述,明确在主进程中的目标:

  1. 开启等同于CPU核数的进程,并将进程保存在进程组(workers)对象中.
  2. 监听进程的死亡,一旦发现.就创建新的进程,并将新的进程替换挂掉的那个进程

子进程:

  1. 创建一个http服务器监听3000端口
  2. 当访问该端口时,以一定的几率报错(让当天进程死亡).
const cluster = require('cluster');
const os = require('os');
const numCPUs = os.cpus().length;
const process = require('process');

// 保存进程组的对象
const workers = {};
if(cluster.isMaster) {
	// 主进程
	for(let i = 0; i< numCPUs; i++){
		const worker = cluster.fork();	// 创建一个进程
		workers[worker['pid']] = worker;	// 保存当前进程
	}
	cluster.on('death', function(worker){
		// 监听进程的死亡
		nWorker = cluster.fork();		// 新建进程
		workers[worker.pid] = nWorker;
	})
} else {
	const Koa = require('koa');
	const app = new Koa();
	app.use(async (ctx, next) => {
		Math.random > 0.95 ? aaa() : '';		// 手动挂掉进程
		console.log(`current process ${process.pid}`);
		await next();
		ctx.body = 'marron';
	})
	app.listen(3000);
}

在这里插入图片描述
当挂的时候,自动重新启动当前服务

发布了177 篇原创文章 · 获赞 22 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/piano9425/article/details/103542084