Apache Tomcat을 운영 환경에서 관리할 때, 기본 제공되는 bin 디렉터리 내부의 스크립트를 직접 실행하는 대신 프로젝트 루트 경로에 래퍼(Wrapper) 스크립트를 두어 관리하는 경우가 많습니다. 이때 가장 주의해야 할 점은 기존에 실행 중인 자바 프로세스가 정상적으로 종료되지 않고 좀비 프로세스로 남는 현상입니다. 이를 방지하기 위해 구동 및 중단 시 잔존 프로세스를 명확히 정리하도록 셸 스크립트를 재구성할 수 있습니다.
톰캣 구동(Start) 스크립트
서버를 시작하기 전에 동일한 톰캣 인스턴스가 이미 실행 중인지 확인하고, 있다면 이를 강제 종료하여 포트 충돌 및 메모리 누수를 방지합니다. grep "[c]atalina" 패턴을 활용하여 grep 프로세스 자체가 검색되는 문제를 해결하고 코드의 가독성을 높였습니다.
#!/bin/bash
# Tomcat Server Start Script
export LANG=ko_KR.UTF-8
export JAVA_HOME=/opt/jdk/jdk1.8.0
export CATALINA_HOME=/opt/tomcat/apache-tomcat-9.0.73
export CATALINA_BASE=$CATALINA_HOME
echo ">>> 톰캣 서버 시작 프로세스를 초기화합니다."
# 실행 중인 기존 톰캣 프로세스 확인
EXISTING_PIDS=$(ps -ef | grep "[c]atalina.base=$CATALINA_BASE" | awk '{print $2}')
if [ -n "$EXISTING_PIDS" ]; then
echo ">>> 실행 중인 기존 톰캣 프로세스를 감지했습니다. PID: $EXISTING_PIDS"
for PID in $EXISTING_PIDS; do
echo ">>> 잔존 프로세스 강제 종료 중: $PID"
kill -9 "$PID"
done
sleep 2
fi
# 톰캣 구동 및 로그 모니터링
if [ -f "$CATALINA_HOME/bin/startup.sh" ]; then
echo ">>> 톰캣 서버를 시작합니다."
sh "$CATALINA_HOME/bin/startup.sh"
sleep 3
NEW_PID=$(ps -ef | grep "[c]atalina.base=$CATALINA_BASE" | awk '{print $2}')
echo ">>> 톰캣 서버가 성공적으로 실행되었습니다. (PID: $NEW_PID)"
echo ">>> 실시간 로그를 출력합니다. (종료하려면 Ctrl+C를 누르세요)"
tail -f "$CATALINA_HOME/logs/catalina.out"
else
echo ">>> 오류: startup.sh 스크립트를 찾을 수 없습니다."
exit 1
fi
톰캣 중단(Stop) 스크립트
서버를 중단할 때는 먼저 톰캣 자체의 shutdown.sh를 통해 우아한 종료(Graceful Shutdown)를 시도합니다. 일정 시간이 지난 후에도 프로세스가 메모리에 남아있다면, 이를 식별하여 안전하게 강제 종료합니다.
#!/bin/bash
# Tomcat Server Stop Script
export LANG=ko_KR.UTF-8
export JAVA_HOME=/opt/jdk/jdk1.8.0
export CATALINA_HOME=/opt/tomcat/apache-tomcat-9.0.73
export CATALINA_BASE=$CATALINA_HOME
echo ">>> 톰캣 서버 중단 프로세스를 시작합니다."
# 정상 종료 시도
if [ -f "$CATALINA_HOME/bin/shutdown.sh" ]; then
echo ">>> 톰캣 서버에 정상 종료 명령을 전달합니다."
sh "$CATALINA_HOME/bin/shutdown.sh"
sleep 5
fi
# 종료 상태 확인 및 잔존 프로세스 강제 종료
REMAINING_PIDS=$(ps -ef | grep "[c]atalina.base=$CATALINA_BASE" | awk '{print $2}')
if [ -z "$REMAINING_PIDS" ]; then
echo ">>> 톰캣 서버가 성공적으로 종료되었습니다."
else
echo ">>> 정상 종료 후에도 잔존하는 프로세스가 있습니다. PID: $REMAINING_PIDS"
for PID in $REMAINING_PIDS; do
echo ">>> 잔존 프로세스 강제 종료 중: $PID"
kill -9 "$PID"
done
echo ">>> 모든 톰캣 프로세스가 강제 종료되었습니다."
fi
exit 0