1. 程式人生 > >pomelo使用採坑記(學習使用部署相關)

pomelo使用採坑記(學習使用部署相關)

pomelo推送方式

pomelo和客戶端保持長連結,推送可以根據頻道推送或者根據使用者連線的伺服器推送

頻道推送

  1. 建立頻道
let channel = this.app.get('channelService').getChannel(channelName, true);
引數1為頻道的名字,引數2為是否在沒有該頻道的時候建立一個
channel.add(uid, sid);
將使用者放到頻道里面,其中uid為使用者唯一標識,sid為connector的伺服器Id

假設伺服器配置是

"connector":[
                       {"id":"c1", "host":"172.16.46.14","port":4050, "clientPort": 3050, "frontend": true,"cpu": 1},
                       {"id":"c2", "host":"172.16.46.14", "port":4051, "clientPort": 3051, "frontend": true,"cpu": 2},
                       {"id":"c3", "host":"172.16.46.14",  "port":4052, "clientPort": 3052, "frontend": true,"cpu": 3},
                       {"id":"c4", "host":"172.16.46.14",  "port":4053, "clientPort": 3053, "frontend": true,"cpu": 4}
         ]

並且使用者123和connector2連線,使用者234連線connector3

channel.add(123, c2);
channel.add(234, c3);
  1. 根據頻道推送
    呼叫
let channel = this.app.get('channelService').getChannel(channelName);
channel.pushMessage(event, msg, cb);
其中event為客戶端監聽的push方法,例如onAdd
msg為推送引數,隨意傳
cb為推送後的回撥函式

以上方法可以給使用者123和使用者234推送同一條訊息

直接推送

  1. 儲存使用者Id和使用者connector伺服器的對應關係
let uids = [];
uids.push({uid:123,sid:"c2"});
uids.push({uid:234,sid:"c3"});
  1. 根據uids推送
this.app.get('channelService').pushMessageByUids(method, params, uids);
其中method為客戶端監聽的push方法,例如onAdd
params為推送引數,隨意傳

bearcat整合

remote和handler整合

  1. 安裝bearcat
npm install --save bearcat
  1. app.js中的配置
var bearcat = require('bearcat');
let contextPath = require.resolve('./context.json');
bearcat.createApp([contextPath]);

bearcat.start(function() {
    Configure();
    app.set('bearcat', bearcat);
    // start app
    app.start();
});

其中context.json為

{
  "name": "myApp",
  "scan": "app",   //需要掃描app資料夾下的所有js檔案
  "beans": []
}
  1. 整合到handler
var bearcat = require('bearcat');
var Handler = function (app) {
    this.app = app;
    this.redis = null;  //假設要用到redis
};
var handler = Handler.prototype;
handler.queryEntry = function (msg, session, next) {
	//自己的業務邏輯
}

module.exports = function (app) {
    return bearcat.getBean({
        id: "gateHandler",
        func: Handler,
        args: [{
            name: "app",
            value: app
        }],
        props: [
            {name: "redis", ref: "redis"}
            ]
    });
};

其他地方需要使用gateHandler的時候,只需要

var other= function () {
    this.gateHandler=null;
}
other.prototype.funA= function(){
	this.gateHandler.queryEntry();
	...
}
module.exports = {
    id: "other",
    func: other,
    props: [
        {name: "gateHandler", ref: "gateHandler"}
    ]
}

非pomelo框架的service、util等的整合

  1. 安裝bearcat
npm install --save bearcat
  1. app.js中的配置
var bearcat = require('bearcat');
let contextPath = require.resolve('./context.json');
bearcat.createApp([contextPath]);

bearcat.start(function() {
    Configure();
    app.set('bearcat', bearcat);
    // start app
    app.start();
});

app.configure('development', 'chat', function() {  //chat型別的伺服器在development環境下的配置
        let chat_OnLineService = bearcat.getBean('chat_OnLineService');
        chat_OnLineService.init(app);
    });

其中context.json為

{
  "name": "myApp",
  "scan": "app",   //需要掃描app資料夾下的所有js檔案
  "beans": []
}
  1. 整合到chat_OnLineService
    檔案onlineService.js中
var OnLineService = function() {};
OnLineService.prototype.init=function (app) {
    this.app = app;
}

module.exports = {
    id: "chat_OnLineService",
    func: OnLineService,
    props: []
}

注意onlineService.js必須在app資料夾下,不然掃描不到
其餘使用方式handler、remote和普通js檔案一模一樣

bearcat優勢

  1. 不需要每次都require,只需要引入bean的id即可,即知道id名字就可以全域性使用
  2. 類似於spring的javabean的方式,適合習慣了使用java框架開發的開發人員快速上手

預設路由規則採坑

未進行使用者Id繫結的多伺服器遠端呼叫

pomelo進行遠端呼叫時(1、系統遠端呼叫,一般呼叫Handler,例如客戶端呼叫pomelo的online.onLineHandler.showOnlinePlayers方法;2、使用者遠端呼叫,一般呼叫Remote,例如app.rpc.chat.onLineRemote.kick,是由使用者在服務端程式碼中直接呼叫),有個預設路由規則

  var uid = session ? (session.uid || '') : '';
  var index = Math.abs(crc.crc32(uid.toString())) % list.length;
  utils.invokeCallback(cb, null, list[index].id);

即先判斷有無session引數傳入,若有則使用session中繫結好的uid否則用空串,然後進行路由。

當用戶未進行session.bind(uid)之前進行遠端呼叫的時候,如果使用者沒有手動配置路由規則,即使有若干同類型的伺服器,也只會呼叫其中的一臺,負載均衡的效果就沒有了。

所以,如果要在未繫結uid的時候進行多埠或者多伺服器的負載均衡,必須要自定義路由規則而不使用預設規則(在進行auth鑑權伺服器呼叫的時候,往往還不知道使用者的Id)

路由配置

exp.auth = function(session, msg, app, cb) {
    let chatServers = app.getServersByType('auth');

    if(!chatServers || chatServers.length === 0) {
        cb(new Error('can not find cron servers.'));
        return;
    }
    cb(null, chatServers[session.id%chatServers.length].id);  //推薦使用session的id或者使用者的裝置資訊等進行路由到不同的伺服器或者埠
};

app.route('auth', routeUtil.auth);

log按照時間日期伺服器分割

按伺服器和天分割

{
      "type": "dateFile",
      "filename": "${opts:base}/logs/cron-${opts:serverId}.log",
      "compress": true,
      "pattern": ".yyyy-MM-dd",
      "layout": {
        "type": "basic"
      }
    ,"backups": 0,
      "category":"cron"
    }

let logger = require('pomelo-logger').getLogger('cron', __filename);
logger.error("***")

按服務端和小時分割

{
      "type": "dateFile",
      "filename": "${opts:base}/logs/service-${opts:serverId}.log",
      "layout": {
        "type": "basic"
      },
      "pattern": ".yyyy-MM-dd-hh",
      "compress": true,
      "backups": 0,
      "category":"service"
    }
let logger = require('pomelo-logger').getLogger('service', __filename);
logger.error("***")

按天分割

{
      "type": "dateFile",
      "filename": "${opts:base}/logs/error.log",
      "compress": true,
      "pattern": ".yyyy-MM-dd",
      "layout": {
        "type": "basic"
      }
    ,"backups": 0,
      "category":"error"
    }
let logger = require('pomelo-logger').getLogger('error', __filename);
logger.error("***")

IDEA調式

伺服器配置

在這裡插入圖片描述

IDEA配置

在這裡插入圖片描述

步驟

  1. List item
  2. node app.js 或者 pomelo start
  3. idea裡面直接斷點,搞定

分散式部署

ssh方式

  1. 假設有2臺機器,A和B
  2. 在A機器上ssh B的ip(內網和外網ip都可以,如果是內網ip則servers.json裡面就要配置內網ip,否則配置外網ip) ,如果不需要設定密碼則進入步驟4,否則進入步驟3
  3. 配置機器A和機器B的ssh互信免密登入,網上一搜一大把…
  4. 在master機器上(假設是A)敲命令 pomelo start -D
  5. 檢視程序是否全部啟動,A機器敲命令 pomelo list
  6. 如果沒有全部啟動,則返回步驟3!

非ssh方式

  1. 假設A機器需要啟動對外7003埠對內4050埠的connector伺服器一臺,B機器需要啟動6053埠的chat伺服器一臺
  2. 則先在A機器上,使用命令
/usr/local/bin/node /data/node/root/app.js env=dev type=all
/usr/local/bin/node /data/node/root/app.js env=dev id=c1 host=172.*.*.* port=4050 clientPort=7003 frontend=true serverType=connector
  1. 在B機器上,使用命令
/usr/local/bin/node /data/node/root/app.js env=dev id=ch4 host=172.*.*.* port=6053 serverType=chat

先寫到這吧··有問題聯絡 滕慶亞