接着上一章节,上一章节主要是介绍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')); }); };
/** * 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}); } };
登记模块完成后,通过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); } };