最近在使用eggjs开发web应用,在docker(centos7.2)环境下部署时遇到些问题,在此记录下:
问题1:Save log file to /xxx/logs
egg通过egg-script启动应用,egg-script的启动日志保存到了用户目录,如终端输入如下:
Save log file to /root/logs
而运维没有开通线上环境的root目录访问权限,egg官方关于日志部分的介绍没有提到如何自定义egg-script启动日志的保存路径。百度了下,发现了这篇文章:
作者也遇到了同样的问题,并给了解决方案。相关代码如下:
//egg-scripts/lib/cmd/start.js
// whether run in the background.
if (isDaemon) {
this.logger.info(`Save log file to ${logDir}`);
const [ stdout, stderr ] = yield [ getRotatelog(argv.stdout), getRotatelog(argv.stderr) ];
options.stdio = [ 'ignore', stdout, stderr, 'ipc' ];
options.detached = true;
再看下logDir的定义:
const HOME = homedir();
const logDir = path.join(HOME, 'logs');
homedir来自node-homedir模块:
const os = require('os');
module.exports = () => {
if (process.env.MOCK_HOME_DIR) return process.env.MOCK_HOME_DIR;
if (os.userInfo && os.userInfo().homedir) {
return os.userInfo().homedir;
} else if (os.homedir) {
return os.homedir();
}
return process.env.HOME;
};
从上面代码的意思可以知道:如果定义了环境变量MOCK_HOME_DIR
,会使用环境变量,否则返回用户根路径,centos的用户根路径为/root/。那我们在启动应用前定义下MOCK_HOME_DIR
环境变量应该可以解决问题:
export MOCK_HOME_DIR = 日志路径
然而并没有作用,是因为不同进程的问题?
不停的查找资料,最后在这个
中找到了答案:自定义MOCK_HOME_DIR
的方法,在start命令中添加:
"start": "MOCK_HOME_DIR=/export/Logs/start egg-scripts start --daemon --title=egg-server-server"
问题2:leader does not be active in xxxms on port xxx
这个问题困扰了我很久,日志如下:
[ClusterClient] nodejs.Error:leader does not be active in 60000ms on port:38205
[egg-scripts] at Function.waitFor (/export/App/server/node_modules/cluster-client/lib/server.js:238:15)
[egg-scripts] at processTicksAndRejections (internal/process/task_queues.js:97:5)
[egg-scripts] at async ClusterClient.[ClusterClient#createClient] (/export/App/server/node_modules/cluster-client/lib/wrapper/cluster.js:42:7)
[egg-scripts] at async ClusterClient.[ClusterClient#init] (/export/App/server/node_modules/cluster-client/lib/wrapper/base.js:71:25)
pid: 530
[egg-scripts] nodejs.Error: [ClusterClient] leader does not be active in 60000ms on port:38205
[egg-scripts] at Function.waitFor (/export/App/server/node_modules/cluster-client/lib/server.js:238:15)
[egg-scripts] at processTicksAndRejections (internal/process/task_queues.js:97:5)
[egg-scripts] at async ClusterClient.[ClusterClient#createClient] (/export/App/server/node_modules/cluster-client/lib/wrapper/cluster.js:42:7)
[egg-scripts] at async ClusterClient.[ClusterClient#init] (/export/App/server/node_modules/cluster-client/lib/wrapper/base.js:71:25)
[egg-scripts]
[egg-scripts] pid: 565
...
日志没有直接指出具体原因,但是从日志中可以看到一些信息,这个错误是来自于cluster-client
(nodejs多进程解决方案,可以充分利用多核CPU)模块,同时通过pid可以发现,egg-scripts创建个很多进程。那是不是进程数量的问题?查阅了下资料,egg-scripts可以设置进程数量,start命令中添加--workers
即可:
"start": "MOCK_HOME_DIR=/export/Logs/start egg-scripts start --daemon --title=egg-server-server --workers 4"
问题很快得到解决,再看下--workers参数的定义:
- `workers` - numbers of app workers, default to `process.env.EGG_WORKERS`, if unset, egg will use `os.cpus().length` as default.
默认数量是cpu的内核数量,打印了下线上机器是96核,docker限制了最大进程数量了吗...