Come già affermato in questo post, nodejs ha rappresentato una vera e propria rivoluzione nella programmazione Web, in quanto ha consentito ad un linguaggio nativamente client-side come javascrip, di essere riadattato ed utilizzato come linguaggio server-side.
Il funzionamento del suddetto applicativo è abbastanza banale: si richiama il binario da CLI e gli si da in pasto il file di configurazione del “server javascrip”, ad esempio:
[root@linuxbox ~]# node server.js
Per lasciarlo attivo in background occorre utilizzare un tool apposito come screen oppure un semplice nohup:
[root@linuxbox ~]# nohup node server.js
Va da se che tale soluzione per “demonizzare” nodejs non è proprio pulitissima ed è per questa ragione che ho deciso di creare un demone ad hoc per il suddetto applicativo:
#!/bin/bash
# chkconfig: 2345 95 20
# description: nodejs service
# processname: nodejs
. /etc/rc.d/init.d/functions
USER="node"
DAEMON="/usr/bin/node"
ROOT_DIR="/home/nodejs"
SERVER="$ROOT_DIR/server.js"
for i in {1..8}
do
do_start()
{
PORT="900$i"
LOG_FILE="$ROOT_DIR/server$i.js.log"
result=`ps aux | grep "server.js $PORT" | grep -v grep`
if [ -z "$result" ] ; then
echo -n $"Starting $SERVER $i: "
runuser -l "$USER" -c "$DAEMON $SERVER $PORT >> $LOG_FILE &" && echo_success || echo_failure
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
else
echo "$SERVER $i already started."
RETVAL=1
fi
}
do_status()
{
PORT="900$i"
result=`ps aux | grep "server.js $PORT" | grep -v grep`
if [ -n "$result" ] ; then
echo "$SERVER $i is started."
RETVAL=0
else
echo "$SERVER $i is stopped."
RETVAL=1
fi
}
done
do_stop()
{
echo -n $"Stopping $SERVER:"
killall -w node
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
}
case "$1" in
start)
for i in {1..8}
do
do_start
done
;;
stop)
do_stop
;;
status)
for i in {1..8}
do
do_status
done
;;
restart)
do_stop
for i in {1..8}
do
do_start
done
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
RETVAL=1
esac
exit $RETVAL
Tale demone, ad ogni avvio, esegue 8 istanze di nodejs, ciascuna delle quali è in ascolto su una porta dedicata (dalla 9001 alla 9008). Per non definire 8 funzioni do_start() e do_status() ho utilizzato un banale ciclo for e poichè la funzione do_stop() effettua un kill di tutti i processi il cui nome contiente la stringa “node” (killall -w), essa è stata estromessa dal predetto loop.
Inoltre, per ragioni di sicurezza, è stato definito un utente dedicato per l’esecuzione dell’applicativo (USER=”node”), la cui root directory è la propria home (ROOT_DIR=”/home/nodejs/), mentre il file di configurazione di nodejs è specificato all’interno della variabile SERVER (SERVER=”$ROOT_DIR/server.js”).
Infine, all’interno della funzione do_start(), ho definito il file di log per ciascuna istanza di nodejs, utilizzando la direttiva LOG_FILE=”$ROOT_DIR/server$i.js.log”.
Per completezza, di seguito riporto anche la versione senza cicli for:
#!/bin/bash
# chkconfig: 2345 95 20
# description: nodejs service
# processname: nodejs
. /etc/rc.d/init.d/functions
USER="node"
DAEMON="/usr/bin/node"
ROOT_DIR="/home/nodejs/"
SERVER="$ROOT_DIR/server.js"
PORT1="9001"
PORT2="9002"
PORT3="9003"
PORT4="9004"
PORT5="9005"
PORT6="9006"
PORT7="9007"
PORT8="9008"
LOG_FILE1="$ROOT_DIR/server1.js.log"
LOG_FILE2="$ROOT_DIR/server2.js.log"
LOG_FILE3="$ROOT_DIR/server3.js.log"
LOG_FILE4="$ROOT_DIR/server4.js.log"
LOG_FILE5="$ROOT_DIR/server5.js.log"
LOG_FILE6="$ROOT_DIR/server6.js.log"
LOG_FILE7="$ROOT_DIR/server7.js.log"
LOG_FILE8="$ROOT_DIR/server8.js.log"
do_start1()
{
result1=`ps aux | grep "server.js $PORT1" | grep -v grep`
if [ -z "$result1" ] ; then
echo -n $"Starting $SERVER 1: "
runuser -l "$USER" -c "$DAEMON $SERVER $PORT1 >> $LOG_FILE1 &" && echo_success || echo_failure
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
else
echo "$SERVER 1 already started."
RETVAL=1
fi
}
do_start2()
{
result2=`ps aux | grep "server.js $PORT2" | grep -v grep`
if [ -z "$result2" ] ; then
echo -n $"Starting $SERVER 2: "
runuser -l "$USER" -c "$DAEMON $SERVER $PORT2 >> $LOG_FILE2 &" && echo_success || echo_failure
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
else
echo "$SERVER 2 already started."
RETVAL=1
fi
}
do_start3()
{
result3=`ps aux | grep "server.js $PORT3" | grep -v grep`
if [ -z "$result3" ] ; then
echo -n $"Starting $SERVER 3: "
runuser -l "$USER" -c "$DAEMON $SERVER $PORT3 >> $LOG_FILE3 &" && echo_success || echo_failure
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
else
echo "$SERVER 3 already started."
RETVAL=1
fi
}
do_start4()
{
result4=`ps aux | grep "server.js $PORT4" | grep -v grep`
if [ -z "$result4" ] ; then
echo -n $"Starting $SERVER 4: "
runuser -l "$USER" -c "$DAEMON $SERVER $PORT4 >> $LOG_FILE4 &" && echo_success || echo_failure
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
else
echo "$SERVER 4 already started."
RETVAL=1
fi
}
do_start5()
{
result5=`ps aux | grep "server.js $PORT5" | grep -v grep`
if [ -z "$result5" ] ; then
echo -n $"Starting $SERVER 5: "
runuser -l "$USER" -c "$DAEMON $SERVER $PORT5 >> $LOG_FILE5 &" && echo_success || echo_failure
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
else
echo "$SERVER 5 already started."
RETVAL=1
fi
}
do_start6()
{
result6=`ps aux | grep "server.js $PORT6" | grep -v grep`
if [ -z "$result6" ] ; then
echo -n $"Starting $SERVER 6: "
runuser -l "$USER" -c "$DAEMON $SERVER $PORT6 >> $LOG_FILE6 &" && echo_success || echo_failure
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
else
echo "$SERVER 6 already started."
RETVAL=1
fi
}
do_start7()
{
result7=`ps aux | grep "server.js $PORT7" | grep -v grep`
if [ -z "$result7" ] ; then
echo -n $"Starting $SERVER 7: "
runuser -l "$USER" -c "$DAEMON $SERVER $PORT7 >> $LOG_FILE7 &" && echo_success || echo_failure
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
else
echo "$SERVER 7 already started."
RETVAL=1
fi
}
do_start8()
{
result8=`ps aux | grep "server.js $PORT8" | grep -v grep`
if [ -z "$result8" ] ; then
echo -n $"Starting $SERVER 8: "
runuser -l "$USER" -c "$DAEMON $SERVER $PORT8 >> $LOG_FILE8 &" && echo_success || echo_failure
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
else
echo "$SERVER 8 already started."
RETVAL=1
fi
}
do_status1()
{
result1=`ps aux | grep "server.js $PORT1" | grep -v grep`
if [ -n "$result1" ] ; then
echo "$SERVER 1 is started."
RETVAL=0
else
echo "$SERVER 1 is stopped."
RETVAL=1
fi
}
do_status2()
{
result2=`ps aux | grep "server.js $PORT2" | grep -v grep`
if [ -n "$result2" ] ; then
echo "$SERVER 2 is started."
RETVAL=0
else
echo "$SERVER 2 is stopped."
RETVAL=1
fi
}
do_status3()
{
result3=`ps aux | grep "server.js $PORT3" | grep -v grep`
if [ -n "$result3" ] ; then
echo "$SERVER 3 is started."
RETVAL=0
else
echo "$SERVER 3 is stopped."
RETVAL=1
fi
}
do_status4()
{
result4=`ps aux | grep "server.js $PORT4" | grep -v grep`
if [ -n "$result4" ] ; then
echo "$SERVER 4 is started."
RETVAL=0
else
echo "$SERVER 4 is stopped."
RETVAL=1
fi
}
do_status5()
{
result5=`ps aux | grep "server.js $PORT5" | grep -v grep`
if [ -n "$result5" ] ; then
echo "$SERVER 5 is started."
RETVAL=0
else
echo "$SERVER 5 is stopped."
RETVAL=1
fi
}
do_status6()
{
result6=`ps aux | grep "server.js $PORT6" | grep -v grep`
if [ -n "$result6" ] ; then
echo "$SERVER 6 is started."
RETVAL=0
else
echo "$SERVER 6 is stopped."
RETVAL=1
fi
}
do_status7()
{
result7=`ps aux | grep "server.js $PORT7" | grep -v grep`
if [ -n "$result7" ] ; then
echo "$SERVER 7 is started."
RETVAL=0
else
echo "$SERVER 7 is stopped."
RETVAL=1
fi
}
do_status8()
{
result8=`ps aux | grep "server.js $PORT8" | grep -v grep`
if [ -n "$result8" ] ; then
echo "$SERVER 8 is started."
RETVAL=0
else
echo "$SERVER 8 is stopped."
RETVAL=1
fi
}
do_stop()
{
echo -n $"Stopping $SERVER:"
killall -w node
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
}
case "$1" in
start)
do_start1
do_start2
do_start3
do_start4
do_start5
do_start6
do_start7
do_start8
;;
stop)
do_stop
;;
status)
do_status1
do_status2
do_status3
do_status4
do_status5
do_status6
do_status7
do_status8
;;
restart)
do_stop
do_start1
do_start2
do_start3
do_start4
do_start5
do_start6
do_start7
do_start8
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
RETVAL=1
esac
exit $RETVAL
Basta dare una semplice occhiata e vi renderete subito conto del perchè abbia preferito la prima versione a quest’ultima.
Non ci rimane che rendere il demone eseguibile:
[root@linuxbox ~]# chmod +x nodejs
spostarlo nella directory /etc/init.d:
[root@linuxbox ~]# mv nodejs /etc/init.d
ed avviarlo:
[root@linuxbox ~]# service nodejs start
E’ tutto.