koa服务器后台:Node.js 通过进程、线程优化的性能
Author:zhoulujun Date:
node.js 单线程的特点
node.js 以异步非阻塞单线程,作为其执行速度的保障。
高性能(不用考虑多线程间来回调用引起性能的损耗)
线程安全(不用担心同意变量会被多线程进行读写而造成程序的崩溃)
底层多线程
说node.js 是单线程其实也是不全面的,node.js 底层库会使用libuv调用多线程来处理I/O 操作。这就像食堂只有一个窗口,只能有按顺序一个个的接收点餐,但是后厨配菜的员工却有很多,他们各司其职保证出餐的速度。
什么是非阻塞单线程?
参考:
弄懂javascript的执行机制:事件轮询|微任务和宏任务|定时器 https://www.zhoulujun.cn/html/webfront/ECMAScript/js6/2015_1110_345.html
如何通过多线程提高node.js 的性能
使用 nodejs 的 koa 框架作为后端服务时,为了充分利用服务器的核数,可以创建与cpu 数量相同的进程数。
创建多进程中可以使用 child_process 也可以使用 cluster。
但是创建了多个进程后还需要考虑负载均衡。因为 cluster 中自己做了负载均衡的算法: round-robin(新连接由主进程接受,然后由它选择一个可用的 worker 把连接交出去,说白了就是轮转法)所以使用 cluster
这里创建进程时,让子进程监听同一端口。
可能会问:多个子进程监听同一端口会报错啊。
实际上,在 node 中进行了处理。当有多个进程监听端口时,Master 进程创建一个 Socket 并绑定监听到该目标端口,通过与子进程之间建立 IPC 通道之后,通过调用子进程的 send 方法,将 Socket(链接句柄)传递过去。端口只会被主进程绑定监听一次,但是主进程和子进程在建立 IPC 通信之后,发送 Socket 到子进程实现端口共享,在之后 Master 接收到新的客户端链接之后,通过负载均衡技术再转发到各 Worker 进程
https://nodejs.org/dist/latest-v8.x/docs/api/cluster.html
const Koa = require('Koa');
const koaRouter = require('koa-router');
const numCpus = require('os').cpus().length;
const cluster = require('cluster');
if (cluster.isMaster) {
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
// 监听worker
cluster.on('listening', function (worker, address) {
console.log(
'listening: worker ' +
worker.process.pid +
', Address: ' +
address.address +
':' +
address.port +
',' +
address.addressType
);
});
// 监听worker退出事件,code进程非正常退出的错误code,signal导致进程被杀死的信号名称
cluster.on('exit', function (worker, code, signal) {
console.log(
'工作进程 %d 关闭 (%s)(%s). 重启中...',
worker.process.pid,
signal || code
);
cluster.fork();
});
} else {
const app = new Koa();
app.use(cors());
app.use(bodyParser());
route(app);
app.listen(3000);
}
如何通过多进程提高node.js 的性能
具体参看:https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html
main.js
const Koa = require('Koa');
const koaRouter = require('koa-router');
const fork = require('child_process').fork;
const app = new Koa();
const router = new koaRouter();
app.use(router['routes']());
router.get('/', function(ctx, next) {
var worker = fork('./work_fibo.js');
worker.on('message', function(m) {
if ('object' === typeof m && m.type === 'fibo') {
worker.kill();
ctx.body = m.result.toString();
}
});
worker.send({type: "fibo", num: 35}, (err) => {
console.log(`${err}`);
});
console.log(`${worker.pid}`);
});
if (!module.parent) {
app.listen(8080);
console.log(`Server was start.`);
}
work_fibo.js
var fibo = function fibo(n) {
return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
}
process.on('message', function(m) {
if (typeof m === 'object' && m.type === 'fibo') {
var num = fibo(m.num);
process.send({type: 'fibo', result: num});
}
});
process.on('SIGHUP', function() {
process.exist();
});
参考文章:
koa cluster 使用多进程 https://blog.csdn.net/qq_42535651/article/details/116610502
Node.js 通过进程、线程优化的性能 https://www.jianshu.com/p/f25388f030be
转载本站文章《koa服务器后台:Node.js 通过进程、线程优化的性能》,
请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/nodejs/8830.html