Tomcat Overview
Apache Tomcat 기본 구조, 디렉터리, 설정 파일
📚 시리즈 네비게이션
| 이전 | 현재 | 다음 |
|---|---|---|
| - | Tomcat Overview | Apache vs Nginx |
→ 시리즈 목차
🎯 Tomcat이란?
Apache Tomcat: Java Servlet, JSP, WebSocket을 실행하는 오픈소스 WAS (Web Application Server)
- Apache Software Foundation에서 개발
- Java EE의 Servlet/JSP 스펙 구현체
- 경량 WAS로 가장 많이 사용됨
🆚 Web Server vs WAS
Web Server
정적 콘텐츠를 처리하는 서버.
- HTML, CSS, JS, 이미지 파일 제공
- 예: Apache HTTP Server, Nginx
- 빠르고 가벼움
WAS (Web Application Server)
동적 콘텐츠를 처리하는 서버.
- 비즈니스 로직 실행
- DB 연동, 세션 관리
- 예: Tomcat, JBoss, WebLogic, WebSphere
왜 분리하는가?
flowchart TD Client["Client"] subgraph WebServer["Web Server (Nginx/Apache)"] WS1["• 정적 파일 직접 처리<br/>(HTML, CSS, JS, 이미지)"] WS2["• SSL 종료"] WS3["• 로드밸런싱"] WS4["• 캐싱"] end subgraph WAS["WAS (Tomcat)"] T1["• Servlet/JSP 실행"] T2["• 비즈니스 로직 처리"] T3["• DB 연동"] end Client --> WebServer WebServer -->|"동적 요청만 전달"| WAS
분리의 장점:
| 장점 | 설명 |
|---|---|
| 성능 | 정적 파일은 Web Server가 훨씬 빠름 |
| 보안 | WAS를 외부에 직접 노출하지 않음 |
| 확장성 | WAS만 스케일 아웃 가능 |
| 안정성 | WAS 장애 시 Web Server에서 에러 페이지 처리 |
📂 Tomcat 디렉토리 구조
$CATALINA_HOME/
├── bin/ # 실행 스크립트
│ ├── startup.sh (startup.bat)
│ ├── shutdown.sh (shutdown.bat)
│ ├── catalina.sh (catalina.bat)
│ └── setenv.sh # JVM 옵션 설정 (직접 생성)
│
├── conf/ # 설정 파일
│ ├── server.xml # 메인 설정 (포트, 커넥터, 호스트)
│ ├── web.xml # 기본 웹앱 설정
│ ├── context.xml # 컨텍스트 공통 설정
│ ├── tomcat-users.xml # 사용자/역할 (Manager 접근)
│ └── logging.properties # 로깅 설정
│
├── lib/ # Tomcat 공통 라이브러리 (JAR)
│
├── logs/ # 로그 파일
│ ├── catalina.out # 표준 출력/에러
│ ├── catalina.YYYY-MM-DD.log
│ ├── localhost.YYYY-MM-DD.log
│ └── localhost_access_log.YYYY-MM-DD.txt
│
├── webapps/ # 웹 애플리케이션 배포 디렉토리
│ ├── ROOT/ # 기본 앱 (/)
│ ├── manager/ # 관리자 앱
│ ├── host-manager/ # 가상 호스트 관리
│ └── myapp/ # 사용자 앱 (또는 myapp.war)
│
├── work/ # JSP 컴파일 결과 (서블릿 .java, .class)
│
└── temp/ # 임시 파일
주요 디렉토리 설명
| 디렉토리 | 설명 | 주의사항 |
|---|---|---|
| bin | 실행/종료 스크립트 | setenv.sh로 JVM 옵션 분리 권장 |
| conf | 모든 설정 파일 | server.xml이 핵심 |
| webapps | 애플리케이션 배포 | WAR 파일 또는 폴더 |
| logs | 로그 파일 | catalina.out 용량 관리 필요 |
| work | JSP 컴파일 캐시 | 문제 시 삭제 후 재시작 |
⚙️ 주요 설정 파일
server.xml
Tomcat의 메인 설정 파일. 서버 구조를 정의함.
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<!-- HTTP Connector: 클라이언트 직접 접속 -->
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- AJP Connector: Apache 연동용 -->
<Connector port="8009"
protocol="AJP/1.3"
redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- 접근 로그 -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log"
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>구조 계층:
flowchart TD Server["Server<br/>(Tomcat 인스턴스)"] Service["Service<br/>(보통 1개)"] subgraph Connectors["Connector (여러 개 가능)"] HTTP["HTTP (8080)"] AJP["AJP (8009)"] end Engine["Engine<br/>(요청 처리 엔진)"] Host["Host<br/>(가상 호스트)"] Context["Context<br/>(웹 애플리케이션)"] Server --> Service Service --> Connectors Service --> Engine Engine --> Host Host --> Context
web.xml
웹 애플리케이션의 배포 서술자 (Deployment Descriptor).
위치:
$CATALINA_HOME/conf/web.xml→ 전체 기본값webapps/myapp/WEB-INF/web.xml→ 앱별 설정
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<!-- 서블릿 정의 -->
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>com.example.MyServlet</servlet-class>
</servlet>
<!-- URL 매핑 -->
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!-- 세션 타임아웃 (분) -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<!-- Welcome 파일 -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>context.xml
Context (웹 애플리케이션) 설정.
위치:
$CATALINA_HOME/conf/context.xml→ 전체 공통webapps/myapp/META-INF/context.xml→ 앱별
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- 리소스 (DataSource 등) -->
<Resource name="jdbc/mydb"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mydb"
username="user"
password="password"
maxTotal="20"
maxIdle="10" />
</Context>tomcat-users.xml
Manager 앱 접근 권한 설정.
<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users>
<!-- 역할 정의 -->
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<role rolename="admin-gui"/>
<!-- 사용자 정의 -->
<user username="admin"
password="password"
roles="manager-gui,admin-gui"/>
</tomcat-users>| 역할 | 설명 |
|---|---|
| manager-gui | 웹 Manager 앱 접근 |
| manager-script | 스크립트로 배포 (curl 등) |
| manager-jmx | JMX 프록시 접근 |
| manager-status | 서버 상태만 조회 |
🔌 Connector (포트)
Tomcat이 외부와 통신하는 방법.
| Connector | 기본 포트 | 용도 |
|---|---|---|
| HTTP | 8080 | 클라이언트 직접 접속 |
| HTTPS | 8443 | SSL/TLS 암호화 |
| AJP | 8009 | Apache 연동 (mod_jk, mod_proxy_ajp) |
| Shutdown | 8005 | 서버 종료 명령 수신 |
HTTP Connector 주요 속성
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
maxThreads="200"
minSpareThreads="10"
acceptCount="100"
maxConnections="8192"
URIEncoding="UTF-8" />| 속성 | 기본값 | 설명 |
|---|---|---|
| port | 8080 | 리스닝 포트 |
| connectionTimeout | 20000 | 연결 타임아웃 (ms) |
| maxThreads | 200 | 최대 처리 스레드 |
| minSpareThreads | 10 | 최소 유휴 스레드 |
| acceptCount | 100 | 대기 큐 크기 |
| maxConnections | 8192 | 최대 동시 연결 |
AJP Connector
Apache 연동 시 사용. HTTP보다 효율적 (바이너리 프로토콜).
<Connector port="8009"
protocol="AJP/1.3"
redirectPort="8443"
secretRequired="false" />⚠️ Tomcat 8.5.51+, 9.0.31+부터 AJP가 기본 비활성화됨. 보안상
secretRequired또는address설정 필요.
🚀 실행 및 관리
시작/종료
# 시작
$CATALINA_HOME/bin/startup.sh
# 종료
$CATALINA_HOME/bin/shutdown.sh
# 또는 catalina.sh 직접 사용
$CATALINA_HOME/bin/catalina.sh start
$CATALINA_HOME/bin/catalina.sh stop
# 포그라운드 실행 (디버깅용)
$CATALINA_HOME/bin/catalina.sh run프로세스 확인
# Tomcat 프로세스 확인
ps -ef | grep tomcat
ps -ef | grep java | grep catalina
# 포트 확인
netstat -tlnp | grep 8080
ss -tlnp | grep 8080
# 로그 확인
tail -f $CATALINA_HOME/logs/catalina.outJVM 옵션 설정 (setenv.sh)
bin/setenv.sh 파일을 생성해서 JVM 옵션을 분리 관리함.
#!/bin/bash
# $CATALINA_HOME/bin/setenv.sh
# 힙 메모리 설정
CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
CATALINA_OPTS="$CATALINA_OPTS -Xmx1024m"
# GC 설정
CATALINA_OPTS="$CATALINA_OPTS -XX:+UseG1GC"
# 인코딩
CATALINA_OPTS="$CATALINA_OPTS -Dfile.encoding=UTF-8"
# JMX 모니터링 (선택)
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.port=9090"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
export CATALINA_OPTS📦 애플리케이션 배포
WAR 파일 배포
# WAR 파일을 webapps에 복사하면 자동 배포
cp myapp.war $CATALINA_HOME/webapps/
# 자동으로 압축 해제됨 (unpackWARs="true")
# 접근: http://localhost:8080/myapp/디렉토리 배포
# 압축 풀린 디렉토리도 가능
cp -r myapp/ $CATALINA_HOME/webapps/ROOT 애플리케이션
/ 경로로 접근하려면:
webapps/ROOT/에 배포- 또는
server.xml에서 Context path 지정
<Host name="localhost" appBase="webapps">
<Context path="" docBase="myapp" />
</Host>Manager 앱으로 배포
tomcat-users.xml에 manager-gui 권한 추가http://localhost:8080/manager/html접속- WAR 파일 업로드
🔍 로그 파일
| 로그 파일 | 내용 |
|---|---|
| catalina.out | 표준 출력/에러, 전체 로그 |
| catalina.YYYY-MM-DD.log | Tomcat 내부 로그 (일별) |
| localhost.YYYY-MM-DD.log | 애플리케이션 로그 |
| localhost_access_log.txt | 접근 로그 (access log) |
# 실시간 로그 확인
tail -f $CATALINA_HOME/logs/catalina.out
# 에러만 확인
grep -i error $CATALINA_HOME/logs/catalina.out
# 특정 날짜 로그
cat $CATALINA_HOME/logs/catalina.2026-01-26.logcatalina.out 용량 관리
catalina.out은 계속 커지므로 로테이션 필요함:
# logrotate 설정 (/etc/logrotate.d/tomcat)
/opt/tomcat/logs/catalina.out {
copytruncate
daily
rotate 7
compress
missingok
size 100M
}🔗 시리즈 네비게이션
| 이전 | 다음 |
|---|---|
| - | Apache vs Nginx |
🔗 관련 문서
- Vagrant 3-Tier Architecture Practice - Web/WAS/DB 실습