接着上一章節,上一章節主要是介紹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);
}
};
今天就這樣結束了。