...
Info |
---|
출처 : https://www.lesstif.com/pages/viewpage.action?pageId=22643003 |
tomcat 종료 과정
톰캣은 일반적으로 2개 내지 3개 이상의 포트를 사용한다. 첫 번째는 관리용 Server Port 로 8005 를 사용하며 프로토콜 커넥터마다 개별 포트를 사용하게 된다.
서비스용으로는 "HTTP Connector" 와 "AJP Connector" 를 사용하므로 3개가 되며 SSL Connector 까지 사용하면 총 4개의 포트를 쓰게 된다.
톰캣의 종료 명령어인 shutdown.sh 는 org.apache.catalina.startup.Bootstrap 클래스의 stop() 메소드를 호출하며 이 메소드는 Server Port 에 연결하여 종료 명령을 전송한다.
shutdown.sh 는 텔넷으로 Server Port에 연결한 후에 SHUTDOWN 이라는 문자열을 전송하면 간단하게 흉내낼 수 있다.
...
Code Block |
---|
$ telnet localhost 8005 |
...
telnet: connect to address ::1: Connection refused |
...
Trying 127.0.0.1... |
...
Connected to localhost. |
...
Escape character is '^]'. |
...
SHUTDOWN |
톰캣 우아하게 종료(tomcat shutdown gracefully)
가끔 여러 가지 이유로 톰캣을 구동한 Java VM 이 깨끗하게 종료되지 않는 경우가 있다. 보통 이런 경우는 Server Port 를 사용하는 쓰레드(thread)는 종료되었지만 Connector 쓰레드는 종료되지 않아 shutdown.sh 로 종료할 수 없다.
이럴 때는 직접 pid 를 얻어서 kill 명령어로 시그널을 전송해서 종료시켜야 한다. 이때 KILL(9) 시그널을 전송 하는데 KILL 시그널은 프로세스가 종료 루틴을 제대로 호출하지 못 할수 있으므로 좋은 방법은 아니다.
종료용 signal 인 TERM 시그널을 여러 번 보낸 후에 그래도 종료되지 않으면 최후의 수단으로 KILL 시그널을 전송하는 게 좋다.
pid를 얻고 실행 여부를 확인하고 시그널을 보내는 등의 일련의 작업을 간단한 쉘 스크립트로 구현했으니 shutdown.sh 대신 사용해도 된다.(gist 링크)
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
#!/bin/sh
killproc() {
local servicename=$1
local user=$2
local signal="TERM"
if [ "$#" = 0 ] ; then
echo $"Usage: killproc {servicename} {user} {signal}"
return 1
fi
if [ "$#" = 3 ]; then
signal=$3
fi
PIDS=`ps -eaf|grep ${servicename}|grep -v grep|grep ${user}|awk '{print $2}'`
## process still running..
for p in ${PIDS}
do
if [ ! -z ${p} ] && [ ${p} -gt 0 ];then
echo "kill -${signal} ${p}"
kill -${signal} ${p};
return $?;
else
return 0;
fi
done
}
## tomcat instance name. recommended tomcat running with custom property (aka -Dcom.example.servicename=myWebApp )
SERVICE_NAME=myWebApp
## tomcat home
TC_HOME=/var/tomcat/tomcat-7.0.55
if [ ! -d ${TC_HOME} ];then
TC_HOME=`pwd`
fi
## tomcat process owner name
USER=`whoami`
cd ${TC_HOME}
./bin/shutdown.sh >& /dev/null
sleep 1 # delay 1 sec for tomcat shutting down..
##
for i in 1 2;do
killproc ${SERVICE_NAME} ${USER}
RET=$?
if [ $RET = 0 ];then
break;
fi;
sleep $i;
done
## if still running send KILL signal
killproc "${SERVICE_NAME}" "${USER}" "KILL" |
젠킨스나 기타 지속적인 통합 솔루션에서 톰캣의 핫 디플로이 기능을 이용하여 어플리케이션을 배포할 경우 PermGen 에러가 발생하면 디플로이도 안 되고 톰캣이 제대로 종료되지 않는 경우가 발생한다.
이럴 경우 핫 디플로이대신 SSH 로 변경하고 종료 스크립트로 위 스크립트를 사용하는 방법이 있다.