目前有一个Node.js应用,如用parent.js管理(两个)child.js进程,在parent.js中的做法是:
var cp = require('child_process');
function spawn(server, config) {
logger.log('spawn ' + server); // 输出spawn /usr/local/app/child.js
worker = cp.spawn('node', [server, config]);
worker.on('exit', function(code) {
if(code !== 0) {
logger.log('code = ' + code); // 输出code = 8
spawn(server,config);
}
});
return worker;
}
var worker = spawn('./child.js');
node parent.js正常/etc/init.d/app start启动正常service app start启动出错出错可以参照parent.js源码的注释部分。
附自启动脚本的写法:
#!/bin/sh
NODE_ENV="production"
NODE_APP='app.js'
APP_DIR='/var/www/example.com';
PID_FILE=$APP_DIR/pid/app.pid
LOG_FILE=$APP_DIR/log/app.log
CONFIG_DIR=$APP_DIR/config
PORT=3000
NODE_EXEC=`which node`
###############
# REDHAT chkconfig header
# chkconfig: - 58 74
# description: node-app is the script for starting a node app on boot.
### BEGIN INIT INFO
# Provides: node
# Required-Start: $network $remote_fs $local_fs
# Required-Stop: $network $remote_fs $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop node
# Description: Node process for app
### END INIT INFO
start_app (){
if [ -f $PID_FILE ]
then
echo "$PID_FILE exists, process is already running or crashed"
exit 1
else
echo "Starting node app..."
PORT=$PORT NODE_ENV=$NODE_ENV NODE_CONFIG_DIR=$CONFIG_DIR $NODE_EXEC $APP_DIR/$NODE_APP 1>$LOG_FILE 2>&1 &
echo $! > $PID_FILE;
fi
}
stop_app (){
if [ ! -f $PID_FILE ]
then
echo "$PID_FILE does not exist, process is not running"
exit 1
else
echo "Stopping $APP_DIR/$NODE_APP ..."
echo "Killing `cat $PID_FILE`"
kill `cat $PID_FILE`;
rm -f $PID_FILE;
echo "Node stopped"
fi
}
case "$1" in
start)
start_app
;;
stop)
stop_app
;;
restart)
stop_app
start_app
;;
status)
if [ -f $PID_FILE ]
then
PID=`cat $PID_FILE`
if [ -z "`ps ef | awk '{print $1}' | grep "^$PID$"`" ]
then
echo "Node app stopped but pid file exists"
else
echo "Node app running with pid $PID"
fi
else
echo "Node app stopped"
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
github地址:https://github.com/chovy/node-startup/blob/master/init.d/node-app
问题解决:
1. 在shell脚本中加入export NODE_PATH=/usr/local/lib/node_modules
2. 执行app时,先cd $APP_DIR
UPDATE:
1. 在start_app方法中创建/var/lock/subsys/app文件,这样系统关机时才会调用app脚本的stop_app方法。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
总结下答案:
export NODE_PATH=/usr/local/lib/node_modulescd $APP_DIRstart_app方法中创建/var/lock/subsys/app文件,这样系统关机时才会调用app脚本的stop_app方法。最好
cd到 app 目录去,这样才能确保找到你安装到本地的 node_modules。我猜你在执行
/etc/init.d/app start的时候恰好就在parent.js所在的目录,于是恰好就能正常找到node_modules,给你造成了启动脚本没问题的错觉。而使用service运行时,这个service脚本重置了$PWD,让 node 找不到node_modules,从而导致问题。总是先
cd再执行 node 脚本是避免出错的最好方法~使用绝对路径试试: