pomelo源码解析之模块解析(三)

  • 1. pomelo-admin源码解析

    该模块主要是用于监控服务器的进程。日志、配置、内存等等信息,可自由扩展
    支持monitor类型或者client类型的登录,其中client类型可以额外执行3条控制命令

  • 子模块解析:

    • pomelo-admin/client

      基于pomelo-admin/protocol/mqtt/mqttClient实现的客户端
      连接指定的服务器并处理通讯
      pomelo中 node_modules/pomelo/bin/pomelo中有调用‘adminClient’

    • pomelo-admin/master

      MasterAgent是基于pomelo-admin/protocol/mqtt/mqttServer实现的服务器
      监听client以及monitor的连接并通信。支持请求其他monitor数据、给client/monitor发送数据功能
      其中在client以及monitor连接时,需要进行验证,验证接口可从外部传递进来doAuthUser\doAuthServer

    • pomelo-admin/modules

      这里提供的就是一些可以调用的模块。详见代码

    • pomelo-admin/monitor

      基于pomelo-admin/protocol/mqtt/mqttClient实现的客户端
      连接指定的服务器并处理通讯

    • pomelo-admin/protocol/mqtt

      实现有MqttClient以及MqttServer
      采用了mqtt-connnection + mqtt-package来实现的一套消息流收发功能。
      主要处理publish消息,然后转发topic+payload(json串)。额外增加了超时重连,心跳时间存储功能

    • mqtt简单介绍

      官方文档

    • pomelo-admin并没有使用该类库的实现,而是使用了自己实现的pomelo-admin/protocol/mqtt

      MQTT是基于TCP/IP封装的一套通信协议,消息封装有固定的消息头,提供16种消息类型。
      客户端有3个最基本的操作 subscribe(订阅) unsubscribe(取消订阅) publish(广播)
      服务器收到广播消息后,可以广播给所有订阅了该topic(频道)的客户端
      MQTT只是支持了16种消息类型的结构序列化,以及消息的传递,具体处理逻辑自行编写

      tips: mqtt_client的接口在’mqtt/client.js’中。
      mqtt_server的接口在’mqtt/generate.js’中。
      接口的参数格式可以参照mqtt-packet/README.md

    • mqtt库所实现的客户端和服务器详解
      • 服务器流程

      • 接收消息
        MQTT创建一个服务器(MqttServer\MqttSecureServer),当有客户端连上时生成一个
        MqttServerClient->connection->stream.Writable
        此时已经把实际连上的socket通过pipe介入到了MqttServerClient对象,实际处理函数在Connection.prototype._write
        在这里进行编码解析,并发送消息。需要自行在MqttServerClient对象中注册该事件

      • 处理并返回消息
        服务器收到具体消息后,使用MqttServerClient对象进行处理
        在connection.js中有这样一段代码,处理消息是,先通过generate中对应函数生成发送的编码数据,然后直接写入socket

        for (var k in protocol.types) {
        	var v = protocol.types[k];
        
        	var fun = "" +
        	"   var p = this.generate." + v +"(opts); " +
        	"   if (p instanceof Error) { " +
        	"     this.emit('error', p) " +
        	"   } else { " +
        	"     this.stream.write(p); " +
        	"   } "
        	" } ";
        
        	Connection.prototype[v] = new Function("opts", fun);
        }
        
      • 客户端流程

      • 接收处理消息
        MQTT创建一个客户端(MqttClient)
        this.stream存的就是连接好的socket
        this.conn是一个连接器,依旧是继承自stream.Writable
        连接上服务器后触发:that.conn.connect(that.options);同服务器流程,直接会向服务器发送自身的一些数据
        所以接受消息与服务器一样依旧是Connection类接管。
        具体处理位置在:MqttClient.prototype._setupStream中有定义。

      • 发送消息
        同服务器,generate接管

  • 整体结构

    client,monitor连接masterAgent
    发送register消息注册,其中monitor需要从配置文件中取出自身的token(adminServer.json)进行校验
    之后与masterAgent的通信,client和monitor只能发送自身所对应的topic的消息。例如client: topic=‘client’
    而在masterAgent对每一条连接维护有一个masterSocket,具体消息由onMonitor和onClient处理

  • 消息传输流程

    根据源码可以发现:

    • client发送消息到masterAgent可以调用指令或者调用modules中的’clientHandler’
      这里的指令在consoleService.js中this.commands 查看模块列表、开启禁用模块

    • monitor发送消息到masterAgent可以调用modules中的’masterHandler’

    • masterAgent发送消息到monitor可以调用modules中的’monitorHandler’

    • monitor调用notify,request --> MasterSocket.onMonitor --> 具体模块::masterHandler处理

    • client调用notify,request -> MasterSocket.onClient --> 具体模块::clientHandler处理

    • client调用command -> MasterSocket.onClient --> consoleService.this.commands支持3条命令

    • 一些操作比如禁用模块,也会让masterAgent广播消息通知client和monitor更新数据 // masterAgent.notifyAll等等

  • 对外接口

    consoleServerce:
    对外提供两个接口createMasterConsole,createMonitorConsole
    分别创建一个masterAgent,monitorAgent
    对于那些模块可用是注册上去的,具体在pomelo/lib/util/moduleUtil.js中的registerDefaultModules

  • tips

    实际上pomelo每个普通进程都创建有monitorAgent,master进程创建的是masterAgent。用于监控进程的一些运行状态
    具体代码在:appUtil.loadDefaultComponents最后一行。
    因为monitor的register消息需要校验token,也就是说新添加服务器进程需要添加token(config/adminServer.json)
    否则的话mqttClient会启动失败,失败后会关闭当前进程

    Agent主要是监控,实际上并不影响主体功能,可以自行选择是否需要

  • 2. pomelo-monitor解析

    很简单的模块仅支持linux系统。提供查看进程状态、系统状态的接口
    使用方法:

    var monitor = require(pomelo-monitor);
    
    var param = {
    	pid: process.pid,
    	serverId: 'node-1'
    };
    
    monitor.psmonitor.getPsInfo(param, function(err, data) {
    	console.log('process information is :', data);
    });
    
    monitor.sysmonitor.getSysInfo(function(err, data) {
    	console.log('operating-system information is :', data);
    });
    

猜你喜欢

转载自blog.csdn.net/qq_37543025/article/details/85254923