Recently, I automated the daily build and deployment of a web application to a Tomcat server. My automated build made calls to stop and restart the Tomcat service using a Tomcat service script.
Unfortunately, I found that Tomcat sometimes will hang when quitting. As a result, after several days, I found several instances of Tomcat running and the web server not serving pages. The cause was that the first Tomcat instance, which owned the http port, was hung and the subsequent instances could not grab the http port.
The fix was to manually kill all the Tomcat instances and then start up a new instance. Because I did not wish to potentially do this manually every day, I decided to beef up the Tomcat service script to check for and kill hung Tomcat instances.
Below is the updated “/etc/init.d/tomcat” script:
#
# /etc/init.d/tomcat
#
# This is the init script for starting up the
# Jakarta Tomcat server
#
# description: Starts and stops the Tomcat daemon.
#
# When running using service, the environmental variables are messed
# up so let us explicitly source it. This is OS-specific; in this
# case, the line below is specific to SUSE Linux's root user profile.
source /etc/profile
tomcat=/opt/apache-tomcat-6.0.18
startup=$tomcat/bin/startup.sh
shutdown=$tomcat/bin/shutdown.sh
# Before starting, stop any existing Tomcat instance
start() {
echo -n $"Starting Tomcat service: "
ps -aef | grep apache-tomcat | grep -v grep | gawk -v FS="[ \t]*" '{print $2}' > /tmp/tomcat.pid
if [ -s /tmp/tomcat.pid ]
then
start_after_stop
else
sh $startup
echo $?
fi
}
# Stop, double-check that Tomcat instance has stopped, and then start
start_after_stop() {
stop
ps -aef | grep apache-tomcat | grep -v grep | gawk -v FS="[ \t]*" '{print $2}' > /tmp/tomcat.pid
if [ -s /tmp/tomcat.pid ]
then
start_after_kill
else
sh $startup
echo $?
fi
}
# Kill the Tomcat instance and then start
start_after_kill() {
tomcat_pid=`cat /tmp/tomcat.pid`
kill -9 $tomcat_pid
sleep 2
ps -aef | grep apache-tomcat | grep -v grep | gawk -v FS="[ \t]*" '{print $2}' > /tmp/tomcat.pid
if [ -s /tmp/tomcat.pid ]
then
echo "Error: there is a tomcat process already running."
else
sh $startup
echo $?
fi
}
stop() {
echo -n $"Stopping Tomcat service: "
sh $shutdown
echo $?
sleep 2
}
restart() {
stop
start
}
status() {
ps -aef | grep apache-tomcat | grep -v grep
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"
exit 1
esac
exit 0
That is as bulletproof as I could make it on a first pass. Hopefully someone will find this useful.
Very useful. Many thanks!