Well, on FreeBSD, various parts of the mongrel cluster crash, and on Linux they seem to spiral out of control and consume a lot of RAM and CPU. I don't every plan on learning ruby, so the cronjob applies the whack-a-mole technique: whenever a mongrel runs astray, we kick it in the ribs and then it starts behaving.
!/bin/sh
### Copyright (c) 2008, Rudy Rucker All rights reserved.
### Redistribution and use of script, with or without modification, is
### permitted provided that the following condition is met:
### Redistributions of source code must retain the above copyright
### notice, this list of conditions and the following disclaimer.
### THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
### ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
### IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
### ARE DISCLAIMED.
# mongrel restart script.
# + added 'check', Tue Apr 3 11:49:58 PDT 2007 - rudy
# + added ram check, Thu Jul 17 14:23:35 PDT 2008 - rudy
#
# Add the next two lines to root's crontab
### monitor mongrel and restart if it has crashed
##*/10 * * * * /usr/local/etc/rc.d/mongrel.sh check
NAME='mongrel'
PATH='/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin'
## The folder you need to start mongrel from
DOGHOUSE='/some/path/to.the.rails/current'
## Need to pull the number of servers out of this CONF file...
NUMBER=0
CONF="${DOGHOUSE}/config/mongrel_cluster.yml"
NUMBER=`grep '^servers' $CONF | awk '{print \$2}'`
# KiloByte limit per mongrel process... a safe value is calculated like this:
# (Total Ram RAM in box) * 90% / Number of Mongrels running
# You may want to pick a higher value if you only get a periodic run-away mongrel.
MAX_RAM_PER_MONG=300000
# If the site ever goes from DEV to something else, this next line needs to be fixed.
# Basically, PIDFILES variable needs to contain every pid-file-name. The redirect
# errors to dev null makes it so ugly errors are not displayed if mongel is not running.
PIDFILES=`ls ${DOGHOUSE}/log/mongrel.*.pid 2> /dev/null`
case "$1" in
restart)
echo -n "re"
$0 start
;;
start)
echo "starting $NAME"
$0 stop
cd ${DOGHOUSE}
/etc/init.d/mongrel_cluster restart
;;
check)
RESTART='NO'
IS_RUNNING='NO'
COUNT=0
for PIDFILE in $PIDFILES; do
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
if kill -0 $PID 2> /dev/null; then
IS_RUNNING='YES'
COUNT=`echo "$COUNT + 1" | bc`
else
RESTART='YES'
fi
fi
done
# Check for number of Mongs...
if [ $COUNT -lt $NUMBER ]; then
echo " *** $COUNT mongrels out of $NUMBER are running... "
logger "[WARN] only $COUNT out of $NUMBER mongrels running"
fi
# Check for run away RAM Mong
# Thu Jul 17 14:23:07 PDT 2008, added RAM check. rudy
for RAM in `ps xo rss,comm | grep $NAME | awk '{print $1}'`; do
if [ $RAM -gt $MAX_RAM_PER_MONG ]; then
echo " *** Ram usage too high for $NAME: ${RAM}k (MAX allowed ${MAX_RAM_PER_MONG}k)";
RESTART='YES'
logger "[WARN] runaway mongrel. Using ${RAM}k of RAM. Restarting"
fi
done
# Check to see if anything needs a restart OR if it is not running at all.
if [ $RESTART = 'YES' ] || [ $IS_RUNNING = 'NO' ]; then
echo
echo "Here is a 'ps' of the current mongrels..."
ps xo %mem,%cpu,rss,thcount,cputime,pid,comm | egrep '(COMMAND|mong)'
echo; echo "OK, stopping and restarting the mongrel cluster"
$0 start
elif [ $COUNT -lt $NUMBER ]; then
echo "Not all ${NAME}s are up. Issuing a restart of the mongrel cluster."
$0 start
fi
;;
stop)
echo "stopping $NAME"
for PIDFILE in $PIDFILES; do
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
echo -n "Checking for $PID from $PIDFILE"
kill $PID 2> /dev/null; sleep 1;
if kill -0 $PID 2> /dev/null; then
echo -n " ."
kill -9 $PID
sleep 1
fi
if kill -0 $PID 2> /dev/null; then
echo -n " ."
kill -9 $PID
sleep 2
fi
if kill -0 $PID 2> /dev/null; then
echo "! Check to make sure pid $PID is gone..."
echo "! I tried to tell it to stop 3 times and then gave up."
else
rm $PIDFILE 2> /dev/null
fi
echo;
fi
done
### Added killall in case ruby got running and didn't make any PID files.
### Fri Jan 18 16:10:54 PST 2008 - Rudy
killall ruby 2> /dev/null && sleep 1
;;
*)
echo ""
echo "Usage: `basename $0` { start | restart | stop | check }"
echo ""
exit 64
;;
esac
|