Node.js的进程管理的深入理解(8)

事件进行了监听,会调用RoundRobinHandle的distribute方法。

// 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模块的逻辑就走通了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持黑区网络。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/242.html