LabHub

Tomcat & nginx 운영 · Tomcat 구조와 server.xml · 이론

Tomcat 을 열어 보면 무엇이 있는가

LabHub 에서 이어서 보기

한 줄 요약

Tomcat 은 디렉터리 일곱 개의 역할만 알면 대부분의 운영 상황이 설명되고, 그중 실제로 사고를 내는 곳은 bin/setenv.sh·work/·logs/catalina.out 셋이다.

왜 아직도 Tomcat 인가

스프링부트를 쓰면 내장 톰캣이 들어 있으니 java -jar 로 끝난다.
그런데 국내 SI 현장에 나가면 여전히 독립 실행 Tomcat 에 WAR 를 올리는 시스템이
훨씬 많다. 이유는 기술적 선호가 아니다.

그래서 신입에게 첫 주에 떨어지는 일이 "톰캣 좀 띄워 보세요"인 것이다.
그리고 그 순간 systemctl start tomcat 이 안 되는 서버를 만난다.

디렉터리 지도

/opt/tomcat├── bin/       기동·정지 스크립트. catalina.sh, startup.sh, shutdown.sh, setenv.sh├── conf/      설정. server.xml, web.xml, context.xml, tomcat-users.xml, logging.properties├── lib/       톰캣 자신과 모든 웹앱이 공유하는 JAR (JDBC 드라이버를 여기 두는 관행)├── logs/      catalina.out, localhost_access_log.*.txt, 각종 *.log├── webapps/   배포 대상. WAR 를 두면 자동으로 같은 이름 디렉터리로 전개된다├── work/      JSP 를 컴파일한 .java/.class 캐시└── temp/      java.io.tmpdir

현장에서 실제로 문제가 되는 지점만 짚자.

server.xml 의 계층

server.xml 은 러시아 인형이다. 바깥에서 안으로 읽으면 이해가 빠르다.

<Server port="8005" shutdown="SHUTDOWN">      <!-- JVM 하나 -->  <Service name="Catalina">                   <!-- 커넥터들 + 엔진 하나 -->    <Connector port="8080" protocol="HTTP/1.1" ... />   <!-- 바깥과 만나는 문 -->    <Engine name="Catalina" defaultHost="localhost">    <!-- 요청 처리 엔진 -->      <Host name="localhost" appBase="webapps"          <!-- 가상 호스트 -->            unpackWARs="true" autoDeploy="true">        <Valve className="...AccessLogValve" pattern="%h %l %u %t &quot;%r&quot; %s %b" />      </Host>    </Engine>  </Service></Server>

context.xml — 웹앱 단위 설정

conf/context.xml 은 전역, conf/Catalina/localhost/<앱이름>.xml 은 앱별 설정이다.
후자를 쓰면 webapps 바깥에 있는 디렉터리를 서비스할 수 있다(docBase).
배포 산출물을 /app/deploy/order 에 두고 톰캣은 건드리지 않는 운영 방식이 여기서 나온다.

DB 커넥션 풀(<Resource>)도 보통 여기 있다. 그래서 "DB 접속 정보 어디 있어요"의
답은 대개 context.xml 이거나 애플리케이션의 프로퍼티 파일 둘 중 하나다.

기동과 정지 — systemd 가 없을 때

# 기동 (백그라운드, catalina.out 으로 로그)/opt/tomcat/bin/catalina.sh start# 포그라운드 (컨테이너에서 쓰는 방식. 로그가 터미널로)/opt/tomcat/bin/catalina.sh run# 정지 (8005 포트로 SHUTDOWN 전송, 종료 대기)/opt/tomcat/bin/catalina.sh stop 30 -force

stop 뒤의 30 -force 는 "30초 기다리고 안 죽으면 kill" 이다.
운영 스크립트에는 이걸 넣는 것이 좋다. 세션 처리 중인 스레드가 있으면
톰캣은 얌전히 안 죽는 경우가 있다.

기동이 됐는지 확인하는 가장 확실한 방법은 프로세스가 아니라 로그와 포트다.

grep 'Server startup in' /opt/tomcat/logs/catalina.out | tail -1ss -ltn | grep 8080

"프로세스는 떠 있는데 포트가 안 열린 상태"가 실제로 존재한다.
포트 충돌이나 초기화 실패로 커넥터만 죽은 경우다. 프로세스만 보고
"올라왔습니다"라고 보고하면 5분 뒤에 다시 전화를 받는다.

현장에서 만나는 모습

SI 현장에서 톰캣을 만지는 첫 주에 겪는 일은 대개 이 셋 중 하나다.

세 가지 모두 톰캣을 몰라서 생기는 문제가 아니라 어느 파일이 무엇을 하는지 몰라서 생기는 문제다. 그래서 디렉터리 지도가 먼저다.