您的位置:首页 > 其它

pomelo源码分析(四)

2013-03-02 13:39 615 查看
接着上文,上文利用提到程序利用

this._optComponents('start', function(err) {
self.state = STATE_START;
utils.invokeCallback(cb, err);
});


发送命令让刚配置好的服务器模块,执行start命令,现在我们开始分析master.start();

lib/components/master.js

var Master = require('../master/master');

var pro = Component.prototype;

/**
* Component lifecycle function
*
* @param  {Function} cb
* @return {Void}
*/
pro.start = function (cb) {
this.master.start(cb);
};

var Master = require('../master/master');

初始化Master模块

module.exports = Server;

var Server = function(app) {
this.app = app;
this.masterInfo = app.get('master');  //获取master的服务器信息,前文有介绍,从master.json文件里面 ,defaultConfiguration函数里
this.registered = {};

this.masterConsole = admin.createMasterConsole({ //创建一个MasterConsole
port: this.masterInfo.port
});
};


adminConsole 有三种角色,分别是 master,monitor,client

master : 运行在master进程中,监听端口等待monitor和client的连接。主要负责维护所有已注册的连接,消息路由和处理,以及缓存服务器集群状态信息。
monitor : 运行在各个需要监控的服务器进程中(包括master进程)。启动后连接并注册到master,主要负责收集被监控的进程信息,向master汇报。
client : 运行在admin console的web页面。启动后连接并注册到master。主要负责响应用户操作和呈现master返回结果。

其实,此代码写得是masterconsole.主要负责维护所有已注册的连接,消息路由和处理,以及缓冲服务器集群的状态信息

pomelo/node_modules/pomelo-admin/lib/consoleServer.js

/**
* Create master ConsoleService
*
* @param {Object} opts construct parameter
*                      opts.port {String | Number} listen port for master console
*/
module.exports.createMasterConsole = function(opts) {
opts = opts || {};
opts.master = true;  //标记为master服务器
return new ConsoleService(opts);  //根据opts.master 的标记来决定初始化master服务器或monitor服务器,创建consoleService,并返回
};


创建consoleService对象

/**
* ConsoleService Constructor
*
* @class ConsoleService
* @constructor
* @param {Object} opts construct parameter
*                      opts.type {String} server type, 'master', 'connector', etc.
*                      opts.id {String} server id
*                      opts.host {String} (monitor only) master server host
*                      opts.port {String | Number} listen port for master or master port for monitor
*                      opts.master {Boolean} current service is master or monitor
* @api public
*/
var ConsoleService = function(opts) {
EventEmitter.call(this);  //ConsoleService继承EventEmitter 方法
this.port = opts.port;  //设置master服务器端口
this.values = {};
this.master = opts.master;  //服务器类型标记,true为master ,其余为monitor

this.modules = {};

if(this.master) {
this.agent = new MasterAgent(this);  //创建MasterAgent 对象
} else {
this.type = opts.type;
this.id = opts.id;
this.host = opts.host;
this.agent = new MonitorAgent({      //创建MonitorAgent对象
consoleService: this,
id: this.id,
type: this.type
});
}
};

util.inherits(ConsoleService, EventEmitter); //在ConsoleService下,创建super_ 属性 指向EventEmitter

这里涉及的概念主要有2个,第一个consoleService继承node.js的事件方法,第二个创建MasterAgent或MonitorAgent。

第一,consoleService继承node.js的事件方法

EventEmitter.call(this); //ConsoleService继承EventEmitter 方法 ,可以 使用 this.emit方法 和 一些事件的监听,如下

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);
}
});


util.inherits() node.js的util提供的方法 http://docs.cnodejs.net/cman/util.html#util_
util.inherits(constructor, superConstructor)

Inherit the prototype methods from one constructor into another. The prototype of constructor will be set to a new object created from superConstructor.

将一个构造函数的原型方法继承到另一个构造函数中。constructor构造函数的原型将被设置为使用superConstructor构造函数所创建的一个新对象。

As an additional convenience, superConstructor will be accessible through the constructor.super_ property.

此方法带来的额外的好处是,可以通过constructor.super_属性来访问superConstructor构造函数。

var util = require("util");
var events = require("events");

function MyStream() {
events.EventEmitter.call(this);
}

util.inherits(MyStream, events.EventEmitter);

MyStream.prototype.write = function(data) {
this.emit("data", data);
}

var stream = new MyStream();

console.log(stream instanceof events.EventEmitter); // true
console.log(MyStream.super_ === events.EventEmitter); // true

stream.on("data", function(data) {
console.log('Received data: "' + data + '"');
})
stream.write("It works!"); // Received data: "It works!"


第二,MasterAgent和MonitorAgent作用

consoleService,是整个监控模块的总入口,master和monitor上都需要创建。各个进程向consoleService注册各自的module。ConsoleService根据当前服务器类型,创建底层的agent实例,并负责agent的启动和关闭。consoleService同时也充当了map的角色,缓存收集到的状态信息。
masterAgent,在master进程中启动,负责底层网络通讯相关工作。如:监听端口,接收monitor和client连接,分组维护这些连接以及将消息推送给指定的接收者等。
monitorAgent,在各个需要监控进程中启动(包括master进程)。启动后连接并注册到masterAgent,负责与masterAgent之间的通讯。
module,监控模块接口,实现监控相关的具体逻辑。定义三个回调接口,分别对应于master,monitor和client上的逻辑。

接下来,我们继续看ConsoleService 里会初始化一个MasterAgent

MasterAgent

if(this.master) {
this.agent = new MasterAgent(this);
}


var MasterAgent = function(consoleService) {
EventEmitter.call(this);
this.consoleService = consoleService;
this.server = null;
this.idMap = {};
this.typeMap = {};
this.clients = {};
this.reqId = 1;
this.callbacks = {};
this.state = ST_INITED;
};


MonitorAgent

this.type = opts.type;
this.id = opts.id;
this.host = opts.host;
this.agent = new MonitorAgent({
consoleService: this,
id: this.id,
type: this.type
});


var MonitorAgent = function(opts) {
EventEmitter.call(this);
this.consoleService = opts.consoleService;
this.id = opts.id;
this.type = opts.type;
this.socket = null;
this.reqId = 1;
this.callbacks = {};
this.state = ST_INITED;
};
总结一下流程,代码需要执行master.start()的时候,需要对master进行初始化,初始化的过程中,会初始化createMasterConsole -> 初始化ConsoleService并返回-> 初始化MasterAgent。ConsoleService相当于agent的总代理,我们有事情就找ConsoleService,consoleservice会找到合适的对象去处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: