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