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.