使用PM2部署pomelo服务器

pomelo服务器部署问题

pemelo可以使用 'pomelo start -e production' 命令在服务器运行生产环境的服务器代码。pomelo自身缺少进程监控,运行过程中不方便获取到进程的运行信息。而且pomelo没有进程保护,当进程崩溃之后,不能自动重启进程。pomelo提供的单服务器重启动功能不能使用,至少目前的2.2.5版本中不能使用单个服务器重启功能。当完成某个服务器的代码的修改之后,只能把全部服务器关掉,之后再全部启动一次。只修改后端服务器的代码,要让代码生效只能全部重启一次,会导致全部玩家断线重新连接。如果只是单独重启一个后端服务器,则不会出现全部客户端断线重连的问题。

pm2配置文件

使用PM2部署项目,需要一份部署配置文件,用于描述pomelo服务器的进程信息。pomelo的进程主要包括master进程和各个功能服务器。

master进程的配置,配置文件需要指定 log文件的目录,项目代码的目录。还有重要的一点是要指定进程的模式mode=stand-alone,如果不指定master进程的模式,导致pomelo多次启动服务器进程,然后会看到系统里有不少重复进程。

{
  "name": "master",
  "script": "app.js",
  "args": [
    "serverType=master",
    "id=master-server-1",
    "host=47.100.96.55",
    "port=4060",
    "env=production",
    "mode=stand-alone"
  ],
  "watch": false,
  "out_file": "./logs/master-server-1_app.log",
  "error_file": "./logsmaster-server-1_error.log",
  "cwd": "/root/pomelo/PirateClashPomeloServer/game-server",
  "merge_logs": true,
  "exec_mode": "fork_mode"
}

其他功能服务器,需要配置各自的端口号码和host地址。具体的配置信息根据server.json的配置来。


{
  "name": "gamehttp",
  "script": "app.js",
  "args": [
    "env=production",
    "id=gamehttp",
    "port=4050",
    "host=127.0.0.1",
    "serverType=gamehttp"
  ],
  "watch": false,
  "out_file": "./logs/gamehttp_app.log",
  "error_file": "./logs/gamehttp_error.log",
  "cwd": "/root/pomelo/PirateClashPomeloServer/game-server",
  "merge_logs": true,
  "exec_mode": "fork_mode"
}
 

使用脚本生成PM2配置文件

当需要修改项目中master.json或者server.json文件时,需要同步去修改 pm2的配置问题,会相当麻烦。于是写了一个node.js脚本,读取master.json 和 server.json的文件内容生成对应的PM2配置文件generatePm2Config.js。 根据实际情况修改变量cwd,envType, 生成的配置文件放到脚本的父目录。


/**
 * Created by superzhan on 2018/3/19.
 *
 * 根据pomelo 的 servers.json 生成 pm2 启动文件
 */

var masterJsonFile = require('../game-server/config/master.json');
var serversJosnFile = require('../game-server/config/servers.json');

//pomelo 源码目录
var cwd='/root/pomelo/PirateClashPomeloServer/game-server';

//配置运行环境 development production
var envType= 'production';

//模板数据
var processConfigType =   {
    "name"        : "",
    "script"      : "app.js",
    "args"        :  [] ,
    "watch": false,
    "out_file": "./logs/app.log",
    "error_file": "./logs/err.log",
    "cwd": "",
    "merge_logs": true,
    "exec_mode": "fork_mode",
};


//最后的结果数据
var resultJson={};
resultJson.apps=new Array();


var  clone = function(origin) {
    if(!origin) {
        return;
    }
    var obj = {};
    for(var f in origin) {
        obj[f] = origin[f];
    }
    return obj;
};

//
var masterConfig = masterJsonFile[envType];
var serversConfig = serversJosnFile[envType];

//生成master 的配置
var pm2Master = clone( processConfigType );
pm2Master.name="master";
pm2Master.args = new Array();
pm2Master.args.push('serverType=master');
pm2Master.args.push('id='+masterConfig.id);
pm2Master.args.push('host='+masterConfig.host);
pm2Master.args.push('port='+masterConfig.port);
pm2Master.args.push('env='+envType);
pm2Master.args.push('mode=stand-alone');
pm2Master.cwd= cwd;
pm2Master.out_file = './logs/'+masterConfig.id+"_app.log";
pm2Master.error_file='./logs'+masterConfig.id+'_error.log';
resultJson.apps.push(pm2Master);

//生成当个服务器的配置
for(serverType in serversConfig)
{
    var servers = serversConfig[serverType];
    for(var i=0;i<servers.length;++i)
    {
        var singleServer= servers[i];

        var appPm2Config =  clone(processConfigType);
        appPm2Config.name=singleServer.id;
        appPm2Config.args= new Array();
        appPm2Config.args.push('env='+envType);
        appPm2Config.args.push('id='+singleServer.id);
        appPm2Config.args.push('port='+singleServer.port);
        appPm2Config.args.push('host='+singleServer.host);
        appPm2Config.args.push('serverType='+serverType);

        if(singleServer.frontend !=null)
        {
            appPm2Config.args.push('frontend='+ singleServer.frontend);
            appPm2Config.args.push('clientPort='+singleServer.clientPort);
        }

        appPm2Config.cwd= cwd;
        appPm2Config.out_file = './logs/'+ singleServer.id+'_app.log';
        appPm2Config.error_file = './logs/'+singleServer.id+'_error.log';

        resultJson.apps.push(appPm2Config);
    }
}



//生成结果数据
var resultFileStr = JSON.stringify(resultJson);
//console.log(resultFileStr);


var fs = require('fs');

fs.writeFile('../pomeloPm2Start.json', resultFileStr, function (err) {
    if (err) {
        console.log(err);
    } else {
        console.log('finish genereate Server pm2 config');
    }
});

PM2管理

启动服务器使用命令 pm2 start pomeloPm2Start.json ,pomeloPm2Start.json是上面生成的配置文件。

监控命令 pm2 monit 查看各个进程的运行状态, pm2 log 输出工程的log, pm2 list 列出所有的服务器进程

单个服务器的重启 pm2 restart processId, processId 对应服务器进程的Id.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容