// RoundRobinHandle this.handle.onconnection = (err, handle) => this.distribute(err, handle); // distribute 对工作进程进行分发 RoundRobinHandle.prototype.distribute = function(err, handle) { this.handles.push(handle); // 存入TCP服务的句柄 const worker = this.free.shift(); // 取出第一个工作进程 if (worker) this.handoff(worker); // 切换到工作进程 }; RoundRobinHandle.prototype.handoff = function(worker) { const handle = this.handles.shift(); // 获取TCP服务句柄 if (handle === undefined) { this.free.push(worker); // 将该工作进程重新放入队列中 return; } const message = { act: 'newconn', key: this.key }; // 向工作进程发送一个类型为 newconn 的消息以及TCP服务的句柄 sendHelper(worker.process, message, handle, (reply) => { if (reply.accepted) handle.close(); else this.distribute(0, handle); // 工作进程不能正常运行,启动下一个 this.handoff(worker); }); };
在子进程中也有对内部消息进行监听,在cluster/child.js
中,有个cluster._setupWorker
方法,该方法会对内部消息监听,该方法的在lib/internal/bootstrap/node.js
中调用,这个文件是每次启动node命令后,由C++模块调用的。
链接
function startup() { // ... startExecution(); } function startExecution() { // ... prepareUserCodeExecution(); } function prepareUserCodeExecution() { if (process.argv[1] && process.env.NODE_UNIQUE_ID) { const cluster = NativeModule.require('cluster'); cluster._setupWorker(); delete process.env.NODE_UNIQUE_ID; } } startup()
下面看看_setupWorker方法做了什么。
cluster._setupWorker = function() { // ... process.on('internalMessage', internal(worker, onmessage)); function onmessage(message, handle) { // 如果act为 newconn 调用onconnection方法 if (message.act === 'newconn') onconnection(message, handle); else if (message.act === 'disconnect') _disconnect.call(worker, true); } }; function onconnection(message, handle) { const key = message.key; const server = handles.get(key); const accepted = server !== undefined; send({ ack: message.seq, accepted }); if (accepted) server.onconnection(0, handle); // 调用net中的onconnection方法 }
最后子进程获取到客户端句柄后,调用net模块的onconnection,对Socket进行实例化,后面就与其他http请求的逻辑一致了,不再细讲。
至此,cluster模块的逻辑就走通了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持黑区网络。