Tomcat
Apache Tomcat
1. 개요
Apache Tomcat은 Apache Software Foundation에서 개발한 오픈 소스 Java Servlet 컨테이너이자 Java Servlet, JavaServer Pages(JSP), Java WebSocket 기술을 구현한 웹 애플리케이션 서버(WAS, Web Application Server)이다.
Tomcat은 단순한 웹 서버(Web Server)를 넘어, Java 기반의 동적 콘텐츠를 생성하고 처리할 수 있는 환경을 제공한다. 특히 Java EE(Enterprise Edition)의 웹 계층 표준인 서블릿 컨테이너 역할을 수행하여, 개발자가 작성한 Java 코드가 HTTP 요청에 따라 실행되고 그 결과가 클라이언트에게 전달될 수 있도록 관리한다.
2. 주요 특징 및 아키텍처
2.1 내부 동작 원리
Tomcat의 들어오면 다음과 같은 흐름으로 처리된다.
[요청 처리 흐름도]
Client $\rightarrow$ <a href="/doc/%EA%B8%B0%EC%88%A0/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/%EC%97%B0%EA%B2%B0%20%EA%B8%B0%EC%88%A0/Connector" class="wiki-link wiki-link-missing">Connector</a> (<a href="/doc/%EA%B8%B0%EC%88%A0/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4/%EB%8F%99%EC%8B%9C%EC%84%B1%20%EC%A0%9C%EC%96%B4/Thread%20Pool" class="wiki-link wiki-link-missing">Thread Pool</a>) $\rightarrow$ Engine $\rightarrow$ Host $\rightarrow$ Context $\rightarrow$ Servlet/JSP $\rightarrow$ Response
- Connector: 특정 포트(기본 8080)를 통해 들어오는 TCP/IP 연결을 수신하고 HTTP 프로토콜을 해석하여 내부 요청 객체로 변환한다. 특히 Connector는 Thread Pool을 관리하며, 요청이 들어오면 가용한 스레드에 할당하여 처리함으로써 효율적인 동시성 제어를 수행한다.
- Engine: Tomcat의 최상위 컨테이너로, 모든 요청을 처리하는 진입점이다. 요청된 호스트 이름을 확인하여 적절한 Host로 전달한다.
- Host: 가상 호스트(Virtual Host)를 정의한다. 하나의 Tomcat 인스턴스에서 여러 개의 도메인을 운영할 때 사용된다.
- Context: 개별 웹 애플리케이션 단위를 의미한다. 요청된 URL 경로(Context Path)에 따라 해당 애플리케이션의 서블릿이나 JSP로 요청을 라우팅한다.
2.2 Web Server vs WAS 비교
Tomcat은 웹 서버의 기능과 WAS의 기능을 모두 가지고 있으나, 전통적인 웹 서버(Apache HTTP Server, Nginx 등)와는 목적이 다르다.
| 구분 | Web Server (웹 서버) | WAS (Web Application Server) |
|---|---|---|
| 주요 역할 | 정적 콘텐츠(HTML, CSS, Image) 제공 | 동적 콘텐츠(DB 조회, 비즈니스 로직) 처리 |
| 처리 방식 | 파일 시스템에서 파일을 읽어 그대로 응답 | 프로그램 실행 후 결과물을 HTML로 생성하여 응답 |
| 예시 | Nginx, Apache HTTP Server | Apache Tomcat, JBoss, WildFly |
| 특징 | 가볍고 빠르며 정적 파일 처리에 최적화 | 서블릿 컨테이너를 포함하며 비즈니스 로직 수행 가능 |
3. 핵심 구성 요소
3.1 서블릿(Servlet) 처리 방식
서블릿은 서버 측에서 실행되는 Java 클래스로, HTTP 요청을 처리하고 응답을 생성하는 역할을 한다. Tomcat은 서블릿의 생명주기(Life Cycle)를 관리하며, 요청이 들어오면 init() $\rightarrow$ service() $\rightarrow$ destroy() 순으로 메서드를 호출한다. 이때 service() 메서드는 요청 방식(HTTP Method)에 따라 doGet(), doPost(), doPut(), doDelete() 등 실제 비즈니스 로직을 처리하는 메서드를 호출하여 응답을 생성한다.
3.2 JSP(JavaServer Pages) 처리 메커니즘
JSP는 HTML 코드 내에 Java 코드를 삽입하여 동적 페이지를 생성하는 기술이다. Tomcat은 JSP 파일을 다음과 같은 단계로 처리한다.
1. 변환(Translation): .jsp 파일을 .java 서블릿 소스 코드로 변환한다.
2. 컴파일(Compilation): 변환된 .java 파일을 .class 바이트코드로 컴파일한다.
3. 실행(Execution): 컴파일된 서블릿 클래스를 메모리에 로드하여 실행하고 결과를 HTML로 출력한다.
4. 설치 및 기본 설정
4.1 설치 요구사항
Tomcat을 실행하기 위해서는 반드시 JDK(Java Development Kit)가 설치되어 있어야 하며, JAVA_HOME 환경 변수가 설정되어 있어야 한다.
4.2 주요 설정 파일
<a href="/doc/%EA%B8%B0%EC%88%A0/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4/%EC%84%A4%EC%A0%95%20%ED%8C%8C%EC%9D%BC/server.xml" class="wiki-link wiki-link-missing">server.xml</a>: 서버의 전체적인 구조, 포트 설정, 가상 호스트, 커넥터 설정을 담당하는 핵심 파일이다.<a href="/doc/%EA%B8%B0%EC%88%A0/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4/%EC%84%A4%EC%A0%95%20%ED%8C%8C%EC%9D%BC/web.xml" class="wiki-link wiki-link-missing">web.xml</a>: 웹 애플리케이션의 배포 서술자(Deployment Descriptor)로, 서블릿 매핑, 필터 설정, 세션 타임아웃 등을 정의한다.
4.3 설정 예시 (XML)
포트 번호를 8080에서 80으로 변경하고, 특정 경로의 컨텍스트를 설정하는 예시는 다음과 같다.
<!-- server.xml 예시 -->
<Service name="Catalina">
<!-- HTTP 포트를 80으로 변경 -->
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<!-- 특정 경로(/myapp)를 실제 물리적 경로와 매핑 -->
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Context path="/myapp" docBase="/home/user/deploy/myapp" reloadable="true" />
</Host>
</Engine>
</Service>
주의: 위 예시의
docBase경로는 리눅스 환경 기준입니다. 실제 설정 시에는 사용 중인 운영체제(Windows, Linux 등)에 맞는 절대 경로로 설정해야 합니다.
[참고] server.xml 주요 속성 상세 설명
port: 서버가 수신 대기할 TCP 포트 번호를 지정한다.protocol: 사용할 HTTP 프로토콜 버전을 지정한다.connectionTimeout: 커넥터가 요청을 기다리는 최대 시간(ms)을 설정한다.appBase: 웹 애플리케이션(WAR 파일 등)이 위치하는 기본 디렉토리를 지정한다.unpackWARs: WAR 파일을 배포할 때 압축을 해제하여 배포할지 여부를 결정한다.autoDeploy: 서버 실행 중appBase내의 변경 사항을 감지하여 자동으로 배포할지 여부를 결정한다.docBase: 웹 애플리케이션의 실제 물리적 위치(디렉토리 또는 WAR 파일 경로)를 지정한다.
5. 배포 및 운영
5.1 WAR 파일 배포
WAR(Web Application Archive)는 웹 애플리케이션의 모든 리소스(클래스, 라이브러리, 설정 파일, 정적 파일)를 하나로 묶은 압축 파일이다.
* 배포 방법: webapps 디렉토리에 .war 파일을 복사하면 Tomcat이 자동으로 압축을 해제하고 배포한다.
* 자동 배포(Auto Deploy): server.xml의 autoDeploy="true" 설정 시, 서버 실행 중에도 webapps 폴더에 파일이 추가/변경되면 즉시 반영되어 서버 재시작 없이 업데이트가 가능하다.
5.2 모니터링 및 로그
Tomcat의 상태 확인과 에러 분석을 위해 로그 파일을 확인한다.
* <a href="/doc/%EA%B8%B0%EC%88%A0/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4/%EB%A1%9C%EA%B7%B8%20%EB%B6%84%EC%84%9D/catalina.out" class="wiki-link wiki-link-missing">catalina.out</a>: 서버의 표준 출력 및 에러 로그가 기록되는 파일로, 서버 기동/종료 및 런타임 예외 확인에 필수적이다.
* localhost_access_log: 클라이언트의 HTTP 요청 기록(IP, 요청 URL, 응답 코드 등)이 남는 파일이다.
6. 성능 최적화 및 보안
6.1 성능 튜닝
- Thread Pool 설정:
maxThreads설정을 통해 동시에 처리 가능한 요청 수를 조절한다. 너무 높으면 메모리 부족이 발생하고, 너무 낮으면 요청 대기 시간이 길어진다. - JVM 힙 메모리:
setenv.sh(또는setenv.bat) 파일에서-Xms(초기 힙 크기)와-Xmx(최대 힙 크기)를 설정하여OutOfMemoryError를 방지한다.
6.2 보안 설정
- 관리자 페이지 제어:
/manager및/host-manager경로에 대한 접근을tomcat-users.xml에서 엄격히 제한하거나, 운영 환경에서는 삭제하는 것이 권장된다. - SSL/TLS 적용:
Connector설정에SSLEnabled="true"를 추가하고 인증서 파일(.jks또는.p12)을 연결하여 HTTPS 통신을 구현한다.
7. 버전별 주요 변경 사항
| 버전 | 주요 변경 및 특징 | 비고 |
|---|---|---|
| Tomcat 7 | Servlet 3.0, JSP 2.2 지원. 비동기 서블릿 처리 도입. | Java 6 이상 |
| Tomcat 8 | Servlet 3.1, JSP 2.3 지원. HTTP/2 프로토콜 지원 시작. | Java 7 이상 |
| Tomcat 9 | Servlet 4.0, JSP 2.3 지원. HTTP/2 표준 지원 강화. | Java 8 이상 |
| Tomcat 10 | Jakarta EE 9 전환. 패키지명이 javax.*에서 jakarta.*로 변경. |
Java 11 이상 |
8. Spring Boot 내장 톰캣과의 차이점
Spring Boot는 '내장 톰캣(Embedded Tomcat)' 방식을 사용하여 별도의 WAS 설치 없이 JAR 파일 실행만으로 서버를 구동한다.
| 구분 | 외장 톰캣 (Standalone) | 내장 톰캣 (Embedded) |
|---|---|---|
| 설치 방식 | Tomcat 설치 $\rightarrow$ WAR 배포 | Spring Boot 애플리케이션에 포함 |
| 관리 주체 | 서버 관리자가 Tomcat 설정 관리 | 개발자가 application.properties로 관리 |
| 배포 단위 | WAR (Web Archive) | JAR (Java Archive) |
| 유연성 | 하나의 Tomcat에 여러 앱 배포 가능 | 앱 하나당 하나의 서버 인스턴스 (마이크로서비스 적합) |
9. 트러블슈팅 및 주요 에러 해결 사례
9.1 주요 에러 코드 및 원인
- HTTP 404 (Not Found): 요청한 리소스가 존재하지 않음. Context Path 설정 오류나 서블릿 매핑 누락 확인 필요.
- HTTP 500 (Internal Server Error): 서버 내부 로직 오류.
catalina.out로그에서 Java Stack Trace 확인 필요. - HTTP 403 (Forbidden): 권한 부족.
web.xml의 보안 설정이나 파일 시스템 권한 확인 필요.
9.2 빈번한 문제 해결
- Port Conflict (포트 충돌):
Address already in use에러 발생 시,netstat -ano | findstr :8080명령어로 해당 포트를 사용하는 프로세스를 찾아 종료하거나server.xml에서 포트를 변경한다. - OutOfMemoryError: 메모리 부족 시 발생하며, Java 8 이전에는 PermGen 영역에서, Java 8 이후에는 Metaspace 영역에서 주로 발생한다. JVM 옵션에서
-Xmx값을 상향 조정하여 해결한다. - ClassNotFoundException / NoClassDefFoundError: 라이브러리 중복 또는 누락 시 발생한다.
WEB-INF/lib폴더 내의 JAR 파일 버전 일치 여부를 확인한다.
이 문서는 AI 모델(gemma-4-31b)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.