[Linux] CentOS7 - Java Web 서버 - 기초환경 설치 및 구성 #01
[Linux] CentOS7 - Java Web 서버 - 실운영을 위한 Tomcat 설정 #02
[Linux] CentOS7 - Java Web 서버 - Oracle 설치 및 설정 #03
[Linux] CentOS7 - GIT을 이용한 버전관리 시스템 구축 #04
Java Web서버 - 실운영을 위한 Tomcat 설정
해당 포스팅은 [Linux] CentOS7 - Java Web서버 - 기초환경 설치 및 구성의 포스팅의 내용에 이어서 작성된 포스팅이다.
이전 포스팅에서 Java Web서버 개발환경 구축을 위한 가장 기본적인 내용을 다루었다면
여기서 진행할 내용은, 굳이 해야할 필요는 없을 수도 있지만.
단순 개발이 아닌, 이제 실운영을 위한 Tomcat 서버 설정의 내용을 담고있기에
해당 노하우를 꼭 경험해 보는것을 추천하는 바이다.
#1. Apaceh Tomcat에 Java JDK 설치경로 직접 지정
프로젝트 진행과정중 실 운용 서버에 기본으로 세팅된 Java JDK와
작업한 프로젝트의 Java JDK의 버전이 달라서 문제가 일어나는 경우가 판이이하다.
이러한 경우 Apache Tomcat에서 사용할 Java JDK를 직접 지정하여 해결한다.
1) Java JDK 설치 경로 확인
먼저 CentOS7에서 Java JDK가 설치된 경로를 확인해 본다.
$ which javac
/usr/bin/javac
$ readlink -f /usr/bin/javac
/usr/java/jdk1.8.0_202-amd64/bin/javac
2) ApacheTomcat에 JAVA_HOM 경로 지정
Tomcat 설치 경로의 setenv.sh 파일을 열고, 위에서 확인한 Java JDK가 설치된 경로를 아래와 같이 추가해준다.
Tomcat의 구동 스크립트인 catalina.sh는 실행에 필요한 환경변수와 JVM 옵션을
setenv.sh를 통해서 사용자들이 설정할 수 있는데
Tomcat은 기본적을 실행될때 아래와 같이 catalina.sh이 setenv.sh 파일을 찾고 setenv.sh의 옵션을 등록하게 된다.
$ sudo vim /usr/local/apache-tomcat-8.5.버전/bin/catalina.sh
~~ 이 하 생 략 ~~
# Ensure that any user defined CLASSPATH variables are not used on startup,
# but allow them to be specified in setenv.sh, in rare case when it is needed.
CLASSPATH=
if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
. "$CATALINA_BASE/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
. "$CATALINA_HOME/bin/setenv.sh"
fi
~~ 이 하 생 략 ~~
위와같이 setenv.sh를 호출하는것을 확인 하였으니
이제 setenv.sh 파일을 만들어서 JAVA_HOME 경로를 지정하자.
$ sudo vim /usr/local/apache-tomcat-8.5.버전/bin/setenv.sh
#!/bin/sh
# JAVA_HOME 경로 지정
JAVA_HOME="/usr/java/jdk1.8.0_202-amd64/"
JAVA_HOME 변수를 생성하고 "/usr/java/jdk1.8.0_202-amd64/" 디렉토리 위치 정보를 추가해 주기만 하면 된다.
#2. Apache Tomcat의 JVM 구동 옵션 설정
기본 Tomcat 설정은 JVM의 메모리가 작게 설정되어 있으니 직접 setenv.sh 파일을 한번더 수정해 주도록 하자.
$ sudo vim /usr/local/apache-tomcat-8.5.버전/bin/setenv.sh
#!/bin/sh
# JAVA_HOME 경로 지정
JAVA_HOME="/usr/java/jdk1.8.0_202-amd64/"
# JVM 옵션 설정
MIN_MEMORY="128m"
MAX_MEMORY="512m"
MAX_PERM_SIZE="256m"
SERVICE_NAME="myWebApp"
JAVA_OPTS="-Dcom.example.servicename=${SERVICE_NAME} -Xms${MIN_MEMORY} -Xmx${MAX_MEMORY} -XX:MaxPermSize=${MAX_PERM_SIZE} ${JAVA_OPTS}"
위 내용은 자바의 가상 머신에 전달할 메모리 관련 설정이며 각 설정의 의미는 다음과 같다.
변수명 | 설명 |
MIN_MEMORY | · 자바 가상 머신에 초기 할당되는 메모리 풀의 크기. · -Xms 옵션의 파라미터로 전달된다. |
MAX_MEMORY | · 자바 가상머신에 할당되는 메모리이 최대 크기. · 규모가 큰 어플리케이션을 구동하거나 시스템에 메모리 여유가 있다면 늘리는 것을 권장한다. |
MAX_PERM_SIZE | · 자바 가상 머신의 PermGen( Permanet Ganeration ) 영역의 크기, 클래스나 메서드, 기타 객체가 저장되는 영역이며 부족할 경우 OutOfMemoryError 가 발생할 수 있다. 특히 Tomcat의 manager를 이용해 핫 디플로이( Hot Deploy )를 한다면 크기를 더 늘려야 한다. |
SERVICE_NAME | · ps 명령어로 현재 구동된 톰캣 어플리케이션의 이름을 가져올 경우 여러개의 JVM이 구동 중이면 grp java로도 원하는 JVM 프로세스를 찾기가 어려울 수 있다. 이를 방지하고 현재 톰캣의 인스턴스를 명확히 구분하기 위해 구동시 서비스명을 지정하면 grep을 이용해 손쉽게 프로세스 정보를 가져올 수 있다. |
JAVA_HOME 추가와 함께 JVM 구동 옵션의 설정까지 모두 완료되었다면
이제 Apache Tomcat을 종료하고 재실행 해주어야 한다.
$ sudo sh /usr/local/apache-tomcat-8.5.버전/bin/shutdown.sh
그런데 이 경우 종종 Apache Tomcat이 정상적으로 종료되지 않아 문제가 되는 일이 발생할 수 있는데,
이경우 아래 내용을 참고하자.
#3. Apache Tomcat이 강제 종료 Shell Script 작성
가끔 톰캣이 제대로 종료되지 않아 서비스 포트는 오픈되어 있고, 관리용 포트만 닫혀 있는 상황으로
JVM( Java Virtual Machine ) 자바 가상머신이 실행중인 경우가 존재한다.
이같은 상황에서는 shutdown.sh 명령을 실행하여도 종료할 수 없고
$ sudo sh /usr/local/apache-tomcat-8.5.버전/bin/shutdown.sh
startup.sh 명령을 실행해도 이미 기존 프로세스가 서비스 포트를 사용하고 있어 구동할 수 없는 상황에 놓이게 된다.
이러한 경우 프로레스 및 파일을 보는 명령어인 lsof를 이용해 PORT를 사용중인 프로세스의 정보를 통해
PID를 알아낸 후 kill 명령어로 종료할 수 있지만,
매번 프로세스 명령을 알아내고 kill 명령으로 강제 종료 해주어야 하는 번거로움을 감수해야 한다.
1) Apache Tomcat 종료 쉘 스크립트( Shell Script ) 제작
Tomcat이 제대로 종료되지 않았을 경우 위에서 설명한 대로 lsof를 이용해 PID를 구한 다음 kill로 종료시킬 수 있지만
lsof의 출력결과를 가공해야 하므로 자동화 하기 어렵다는 단점이 있기에
아래와 같은 쉘 스크립트를 작성하여 Linux 서버에 반영해 보자.
$ sudo vim /usr/local/apache-tomcat-8.5.버전/bin/shutdown_graceful.sh
#!/bin/sh
# 프로세스 이름과 사용자명으로 PID 를 찾아서 종료시키는 함수
killproc() {
local prog=$1
local user=$2
local signal="TERM"
if [ "$#" = 0 ]; then
echo $"Usage: killproc {program} {user} {signal}"
return 1
fi
if [ "$#" = 3 ]; then
signal=$3
fi
PID=`ps -eaf|grep ${prog}|grep -v grep|grep ${user}|awk '{print $2}'`
## process still running..
if [ ! -z ${PID} ] && [ ${PID} -gt 0 ];then
echo "kill -${signal} ${PID}"
kill -${signal} ${PID};
return 1;
else
return 0;
fi
}
# 톰캣 인스턴스 이름.
# grep 으로 프로세스 찾을 때 java 나 tomcat 으로 찾으면
# 여러 개의 프로세스가 나올 수 있으므로 이 이름으로 찾는게 좋다.
# setenv.sh 에 SERVICE_NAME 프로퍼티에 지정한 이름을 적어주자.
SERVICE_NAME="servicename=myWebApp"
# 톰캣 홈 디렉토리.
# 설치 위치에 맞게 수정하자.
# 디렉터리가 없다면 스크립트를 호출한 위치를 톰캣 홈으로 사용한다.
TC_HOME=/usr/local/apache-tomcat-8.5.68
if [ ! -d ${TC_HOME} ];then
TC_HOME=`pwd`
fi
# 사용자 별로 톰캣이 떠 있을수 있으므로 프로세스 소유자 명으로도 필터링한다.
USER=`whoami`
cd ${TC_HOME}
./bin/shutdown.sh >& /dev/null
sleep 1 # 톰캣 정상 종료를 위해 1초 대기
# 루프를 2번 실행
for i in 1 2;do
killproc ${SERVICE_NAME} ${USER}
RET=$?
if [ $RET = 0 ];then
break;
fi;
sleep $i;
done
# 아직도 종료되지 않았다면 KILL 시그널을 전송
killproc "${SERVICE_NAME}" "${USER}" "KILL"
2) 실행 권한 부여
$ sudo chmod +x /usr/local/apache-tomcat-8.5.버전/bin/shutdown_graceful.sh
3) Apache Tomcat 종료
$ sudo sh /usr/local/apache-tomcat-8.5.버전/bin/shutdown_graceful.sh
#4. 별칭( alias )을 이용하여 Tomcat 실행 및 종료 단축 명령 지정
Apache Tomcat을 실행하기 위해서는 Linux 설치 경로에 존재하는
startup.sh, shutdown.sh 파일의 위치를 지정하여 실행해야 한다.
$ sudo sh /usr/local/apache-tomcat-8.5.버전/bin/startup.sh
$ sudo sh /usr/local/apache-tomcat-8.5.버전/bin/shutdown.sh
물론 실제 서비스를 운영을 시작하고나면 수시로 Apache Tomcat을 실행하거나, 종료하는 경우는 없겠지만.
프로젝트를 진행하는 과정중에는 수시로 Tomcat을 재시작 해주어야 하기에
위와같이 명령을 입력하는 것은 매우 비효율 적일 수밖에 없다.
그래서 Linux에서 지원하는 긴 명령어의 별칭을 부여하여 사용을 간소화 해주는 alias를 이용하여
Tomcat의 실행( startup.sh ) 및 종료( shutdown.sh )종료 명령을 별칭을 지정,
빠르게 Apache Tomcat을 종료하고 재기동 할 수 있는 작업을 진행하자.
1) Apache Tomcat의 시작( startup.sh ) 명령 별칭 지정
$ alias tomcat_start='sudo sh /usr/local/apache-tomcat-8.5.버전/bin/startup.sh'
tomcat_start
별칭( alias )를 지정하고 톰캣을 실행 한다.
2) Apache Tomcat의 종료( shutdown.sh ) 명령 별칭 지정
종료명령은 shutdown.sh 가아닌 위에서 제작한 shutdown_graceful.sh 파일을 지정할 것이다.
$ alias tomcat_stop='sudo sh /usr/local/apache-tomcat-8.5.버전/bin/shutdown_graceful.sh'
tomcat_stop
별칭( alias )를 지정하고 톰캣을 종료 한다.
별칭( alias ) 지정한 tomcat_start, tomcat_stop 명령이 제대로 등록되었는 지 한번 확인해 보자.
$ alias
~~ 이 하 생 략 ~~
alias tomcat_start='sudo sh /usr/local/apache-tomcat-버전/bin/startup.sh'
alias tomcat_stop='sudo sh /usr/local/apache-tomcat-버전/bin/shutdown_graceful.sh'
~~ 이 하 생 략 ~~
#5. Apache 웹 서버와 Tomcat 서버 연동
Apache Tomcat은 HTTP 서버 기능을 내장하고 있고,
JAVA NIO를 사용하는 커넥터를 구현하는등 많은 성능향상이 이뤄졌지만
Tomcat 단독으로 사용하기 보다 PHP개발에서 많이 사용하는
Apache 웹 서버등의 별도의 웹 서버와 연계하여 사용하는 경우가 많다.
그 이유를 모두 설명할 수는 없기에 해당 포스팅은 보안상 사용자에게
Apache Tomcat의 포트( 8181 )을 노출 하지않는 보안상의 이유와 사용목적만을 다룬다.
1) Apache Web Server 설치하기
먼저 Apache Web Server를 설치한다.
$ sudo yum install -y httpd
설치가 완료되면 Apache 웹 서버를 실행한다.
$ sudo systemctl start httpd
이제 원격지 컴퓨터에서 웹 브라우저를 열고 Linux( CentOS7 )의 IP 주소를 입력하여
아래와 같은 화면이 노출되는지를 확인하자.
Apache Web Server가 정상 작동하는것이 확인 되었다면 마지막으로 아래 명령을 수행하여
$ sudo systemctl enable httpd
CentOS7 Linux 서버 재부팅시 자동으로 Apache 서버가 실행되도록 설정하여 준다.
2) Apache 버추얼 호스트 설정 - mod_proxy와의 연계
mod_proxy는 아파치 웹 서버에 기본적으로 포함돼 있는 모듈로
포워드 프록시( Forward proxy )와 리버스 프록시( Reverse Proxy ) 역할을 수행하는 모듈이다.
① 버추얼 호스트 설정파일 작성
$ sudo vim /etc/httpd/conf.d/virtual-java.conf
<VirtualHost *:80>
ServerName 서버_IP주소
ServerAlias 서버_IP주소
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://127.0.0.1:8181/
ProxyPassReverse / http://127.0.0.1:8181/
<Location /mywebapp>
Order allow,deny
Allow from all
</Location>
ErrorLog logs/dummy-host.example.com-error_log
CustomLog logs/dummy-host.example.com-access_log common
</VirtualHost>
② Apache Web Server 재시작
$ sudo systemctl restart httpd
③ Apache Web Server - mod_proxy 방식 연동 결과 확인
※ Apache Web Server와의 연계방식 2가지
연계방식에 따라 mod_jk와 mod_proxy라는 두 가지 연계방식이 존재한다.
해당 포스팅에서는 mode_proxy만을 다루었지만,
실 서비스에서는 WAS가 Tomcat이라는 전제 하에서는 전용 바이너리 프로토콜인 mode_jk의 속도가 더 빠르다.
하지만 위에 설명한대로 Tomcat전용 바이너리이기에 Tomcat을 사용하는 경우에 한해 사용해야 한다.
실운영 단계 레벨에서는 mod_jk, mod_proxy 두가지중 상황에 맞는 것을 설정하고 진행하자.
※ SSL 인증을 받고 https 를 사용하게 된 경우 아래 포스팅을 참고
#6. Apache Tomcat 실행 로그( LOG ) 확인
Web Service를 실제로 진행하다 문제가 발생하면 가장 많이 확인하게 되는 사항이
Apache Tomcat의 실행 Log를 확인하는 것이다.
아래 명령은 tail을 사용하여 Apache Tomcat의 catalina.out에 기록되는 Tomcat 실행 LOG 100줄을 출력하는 내용이다.
$ tail -f /usr/local/apache-tomcat-8.0.9/logs/catalina.out -n 100
~~ 이 하 생 략 ~~
DD-MM-YYYY HH:MM:SS INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8181"]
DD-MM-YYYY HH:MM:SS INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
DD-MM-YYYY HH:MM:SS INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
DD-MM-YYYY HH:MM:SS INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
DD-MM-YYYY HH:MM:SS INFO [main] org.apache.catalina.startup.Catalina.load Initialization processed in 1191 ms
DD-MM-YYYY HH:MM:SS INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service Catalina
DD-MM-YYYY HH:MM:SS INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.0.9
~~ 이 하 생 략 ~~
위와같이 tail 명령을 통해 출력 로그를 확인 하였는데
마찬가지로 이 실행 로그 호출 명령 또한 별칭을 지정해 주도록 하자.
$ alias tomcat_logc='tail -f /usr/local/apache-tomcat-8.5.68/logs/catalina.out -n'
$ tomcat_logc 100
그럼 위와같이 별칭으로 명령을 간략히 입력하고 출력할 ROW의 개수값을 추가적으로 작성하는 형태로
Tomcat의 로그 확인이 가능하게 되었다.
해당 포스팅은 필자가 프로젝트시 기본으로 설정하는 Apache Tomcat 사용 방법에 대한
환경설정 방법을 중심으로 작성하였기에 꼭 필수적으로 해야하는 부분은 아니다.
초심자라면 포스팅의 각 파트 하나하나가 무엇을 이야기 하는지 모를 수도 있지만
단순히 따라만 해봐도 "이러한 사용 방법도 있구나" 라는것을 한번쯤 경험만 해보아도
실무에서는 큰 도움이 될거라 생각하기에, 작성을 해 보았다.
해당 포스팅 까지 진행을 해보았다면
[AWS] EC2 - Amazon Linux 2 AMI 서버 구축 포스팅을 참고하여
AWS의 사용까지 범위의 확장을 진행하는것을 추천한다.
'LINUX > CentOS' 카테고리의 다른 글
[Linux] CentOS7 - HTTPS 접속을 위한 Apache 웹 서버의 Mod_Proxy 설정 (0) | 2022.11.15 |
---|---|
[Linux] CentOS7 - GIT을 이용한 버전관리 시스템 구축 (0) | 2021.07.04 |
[Linux] CentOS7 - Java Web 서버 - Oracle 설치 및 설정 (0) | 2021.07.04 |
[Linux] CentOS7 - Java Web 서버 - 기초환경 설치 및 구성 (0) | 2021.07.01 |
[Linux] VirtualBox6 가상머신을 이용한 - CentOS7 설치 (0) | 2021.06.29 |