接着上一章节,上一章节主要是介绍Master Server的初始化,接下来就是初始化后的启动
lib/master/master.js
var Server = function(app) {
this.app = app;
this.masterInfo = app.get('master');
this.registered = {};
this.masterConsole = admin.createMasterConsole({
port: this.masterInfo.port
});
};
Server.prototype.start = function(cb) {
registerDefaultModules(this.app); //注册默认模块
loadModules(this.app, this.masterConsole); //执行模块
var self = this;
this.masterConsole.start(function(err) {
if(err) {
cb(err);
return;
}
starter.runServers(self.app);
cb();
});
this.masterConsole.on('register', function(record) {
logger.debug('[master] new register connection: %j, %j', record.id, record.type);
self.registered[record.id] = record;
if(checkRegistered(self)) {
logger.info('[master] all servers have started and notify after start now...');
self.masterConsole.agent.notifyAll(AfterStart.moduleId);
}
});
this.masterConsole.on('disconnect', function(id, type, reason) {
crashLogger.info(util.format('[%s],[%s],[%s],[%s]', type, id, Date.now(), reason || 'disconnect'));
});
};
registerDefaultModules
/**
* Append the default system admin modules
*/
var registerDefaultModules = function(app) {
app.registerAdmin(require('../modules/console'), {app: app, starter: starter});
if(app.enabled('systemMonitor')) { //启动系统检测
app.registerAdmin(admin.modules.systemInfo); //登记系统信息模块
app.registerAdmin(admin.modules.nodeInfo); //登记节点模块信息
app.registerAdmin(admin.modules.monitorLog,{path: pathUtil.getLogPath(app.getBase())}); //登记日志模块信息
app.registerAdmin(admin.modules.scripts, {app: app, path: pathUtil.getScriptPath(app.getBase())});
app.registerAdmin(admin.modules.profiler, {isMaster: true});
}
};
registerAdmin作用,传输三个参数1.模块名字(参数可选),2.模块对象或工厂方法 3.模块参数,登记在'__module__'内存中
登记模块完成后,通过loadModules加载刚才注册的模块。
/**
* Load admin modules
*/
var loadModules = function(app, consoleService) {
// load app register modules
var modules = app.get('__modules__');
if(!modules) {
return;
}
var record, moduleId, module;
for(var i=0, l=modules.length; i<l; i++){
record = modules[i];
if(typeof record.module === 'function') { //检查模块是否有参数,有参数则传入参数
module = record.module(record.opts);
} else {
module = record.module;
}
moduleId = record.moduleId || module.moduleId;
if(!moduleId) {
logger.warn('ignore an uname module.');
continue;
}
consoleService.register(moduleId, module); //为consoleService 注册模块到对象里面
}
};
ConsoleService.prototype.register = function(moduleId, module) {
this.modules[moduleId] = registerRecord(this, moduleId, module);
};
注册所有模块后,执行start
this.masterConsole.start(function(err) {
if(err) {
cb(err);
return;
}
starter.runServers(self.app);
cb();
});
实际执行代码
/**
* start master or monitor
*
* @param {Function} cb callback function
* @api public
*/
ConsoleService.prototype.start = function(cb) {
if(this.master) { //mater启动配置
this.agent.listen(this.port); //实际调用的是masterAgent.listen
exportEvent(this, this.agent, 'register'); //利用masterAgent 监听'register'事件,并返回到当前事件
exportEvent(this, this.agent, 'disconnect'); //利用masterAgent 监听'disconnect'事件,并返回到当前事件
process.nextTick(function() {
utils.invokeCallback(cb); //检查全局函数里面,是否存在回调函数
});
} else { //monitor启动配置
logger.info('try to connect master: %j, %j, %j', this.type, this.host, this.port);
this.agent.connect(this.port, this.host, cb);
exportEvent(this, this.agent, 'close');
}
exportEvent(this, this.agent, 'error');
for(var mid in this.modules) {
this.enable(mid); //使能所有刚才注册的模块
}
};
根据application所配置的选项,利用命令启动服务器
/**
* Run all servers
*
* @param {Object} app current application context
* @return {Void}
*/
starter.runServers = function (app) {
var servers = app.getServers();
for (var serverId in servers) {
this.run(app, servers[serverId]);
}
};
如果是远端的服务器,则利用ssh命令来启动远端的服务器
/**
* Run server
*
* @param {Object} app current application context
* @param {Object} server
* @return {Void}
*/
starter.run = function (app, server) {
var cmd = util.format('cd %s && node ', app.getBase());
var arg = server.args;
if (arg !== undefined) {
cmd += arg;
}
this.env = app.get('env');
cmd+=util.format(' %s env=%s serverType=%s serverId=%s', app.get('main'), this.env, server.serverType, server.id);
if (isLocal(server.host)) {
starter.localrun(cmd);
} else {
starter.sshrun(cmd, server.host);
}
};
今天就这样结束了。