웹 개발을 하다 보면 Tomcat과 NginX라는 용어를 자주 접하게 된다. 둘 다 웹과 관련된 서버 소프트웨어이지만, 각각의 역할과 특징이 완전히 다르다. 오늘은 이 두 가지를 명확히 구분하고, 언제 어떻게 사용해야 하는지 알아보자.
먼저 웹 서버와 WAS(Web Application Server)의 차이를 이해해야 한다.
웹 서버는 정적 파일(HTML, CSS, 이미지 등)을 클라이언트에게 제공하는 소프트웨어다. 클라이언트의 HTTP 요청을 받아서 이미 만들어진 파일을 그대로 전송하는 역할을 한다.
WAS는 동적 컨텐츠를 생성할 수 있는 서버다. 데이터베이스 조회, 비즈니스 로직 처리 등을 통해 요청에 따라 다른 결과를 만들어내는 역할을 한다. WAS는 웹 서버의 기능도 포함하고 있어 정적 파일도 제공할 수 있다.
WAS가 웹 서버 기능을 포함하고 있음에도 불구하고 둘을 분리해서 사용하는 이유는 다음과 같다
1. 서버 부하 방지
WAS가 정적 파일까지 처리하면 동적 처리에 필요한 리소스가 부족해져 전체적인 성능이 저하된다.
2. 장애 극복(Failover)
웹 서버는 상대적으로 안정적이지만 WAS는 복잡한 로직 처리로 인해 장애가 발생하기 쉽다. 분리하면 WAS 장애 시에도 웹 서버가 오류 페이지를 제공할 수 있다.
3. 효율적인 리소스 관리
정적 컨텐츠가 많으면 웹 서버를 증설하고, 동적 처리가 많으면 WAS를 증설하는 식으로 선택적 확장이 가능하다.
NginX(엔진엑스)는 가볍고 빠른 웹 서버다. 2004년에 등장했으며, 특히 대용량 트래픽을 효율적으로 처리하는 것으로 유명하다.
NginX는 이벤트 기반(Event-Driven) 방식을 사용한다. 하나의 워커 프로세스가 수천 개의 동시 연결을 처리할 수 있어, 메모리 사용량이 적고 성능이 뛰어나다.
전통적인 서버와 달리 NginX는 비동기 방식으로 동작하여, 한 요청을 처리하는 동안에도 다른 요청들을 동시에 처리할 수 있다. 이로 인해 블로킹 없이 높은 동시성을 제공한다.
NginX는 단순히 정적 파일만 제공하는 것이 아니라, 리버스 프록시 역할도 할 수 있다. 클라이언트와 백엔드 서버 사이에서 중재자 역할을 하여 다음과 같은 이점을 제공한다:
적은 메모리와 CPU로도 대용량 트래픽을 처리할 수 있어, 비용 효율적인 서버 운영이 가능하다.
1990년대 말, 인터넷 사용자가 급증하면서 C10K 문제가 대두되었다. 이는 동시 접속자 1만 명을 처리할 수 없는 웹 서버의 한계를 의미한다.
러시아의 개발자 Igor Sysoev는 대형 포털 사이트 Rambler.ru에서 일하면서 Apache 서버의 성능 한계를 직접 경험했다. 이를 해결하기 위해 2002년부터 새로운 웹 서버 개발을 시작했고, 2004년 NginX를 공개했다.
NginX는 이벤트 기반 아키텍처로 Apache의 메모리 사용량과 동시 접속 처리 한계를 혁신적으로 개선했다.
NginX가 등장하기 전에는 Apache HTTP Server가 가장 인기 있는 웹 서버였다. Apache는 다음과 같은 방식으로 동작했다
하지만 인터넷 사용자가 급증하면서 C10K 문제가 발생했다. 이는 동시 접속자 1만 명(10,000 Connection)을 처리할 수 없는 문제를 의미한다. Apache의 구조적 한계였다
2004년, 이러한 Apache의 한계를 극복하기 위해 Igor Sysoev가 NginX를 개발했다.
NginX는 마스터 프로세스(Master Process)와 워커 프로세스(Worker Process)로 구성된다.
마스터 프로세스의 역할:
워커 프로세스의 역할:
이벤트 처리 방식:
1. 클라이언트 연결, 요청 처리, 응답 등을 모두 이벤트로 취급
2. 이벤트들을 큐(Queue)에 담아서 순서대로 처리
3. 비동기 방식으로 대기 - 블로킹되지 않음
4. 하나의 스레드로 여러 이벤트를 순차적으로 처리
전통적인 서버는 하나의 요청을 완전히 처리할 때까지 대기해야 했다. 예를 들어, 파일을 읽거나 데이터베이스에 쿼리를 보내는 동안 해당 스레드는 응답을 기다리며 아무것도 할 수 없었다.
하지만 NginX는 비동기 I/O 처리 방식을 사용한다:
이러한 구조로 인해 NginX는 적은 리소스로도 많은 동시 접속을 처리할 수 있다.
NginX는 단순히 정적 파일만 제공하는 것이 아니라, 리버스 프록시 역할도 할 수 있다. 클라이언트와 백엔드 서버 사이에서 중재자 역할을 하여 다음과 같은 이점을 제공한다:
Tomcat은 Java 서블릿과 JSP를 실행할 수 있는 웹 애플리케이션 서버(WAS)다. Java 웹 애플리케이션을 실행하는 표준 컨테이너 역할을 한다.
Tomcat의 핵심은 서블릿 컨테이너 기능이다. Java 서블릿과 JSP를 실행하고 관리하는 환경을 제공한다. Spring Boot 애플리케이션도 내장 Tomcat을 사용하여 실행된다.
웹 애플리케이션의 생명주기를 관리한다. 애플리케이션 시작, 정지, 재시작 등을 담당하며, 메모리 관리와 세션 관리도 수행한다.
Java Enterprise Edition의 표준 스펙을 따르므로, 다른 Java 웹 프레임워크들과 호환성이 뛰어나다.
각 HTTP 요청을 별도의 스레드에서 처리한다. 스레드 풀을 사용하여 동시에 여러 요청을 처리할 수 있다.
Tomcat을 설치하면 다음과 같은 주요 디렉터리들이 생성된다:
tomcat/
├── bin/ # 실행 파일 및 스크립트
│ ├── startup.sh # 시작 스크립트
│ ├── shutdown.sh # 종료 스크립트
│ └── catalina.sh # 메인 실행 스크립트
├── conf/ # 설정 파일
│ ├── server.xml # 서버 전체 설정
│ ├── web.xml # 웹 애플리케이션 기본 설정
│ └── context.xml # 컨텍스트 설정
├── lib/ # Tomcat 라이브러리
├── logs/ # 로그 파일
├── temp/ # 임시 파일
├── webapps/ # 웹 애플리케이션 배포 디렉터리
│ ├── ROOT/ # 기본 웹 애플리케이션
│ ├── manager/ # 관리자 앱
│ └── docs/ # 문서
└── work/ # JSP 컴파일된 파일
주요 디렉터리 설명:
| 구분 | NginX | Tomcat |
|---|---|---|
| 유형 | 웹 서버 | WAS (웹 애플리케이션 서버) |
| 주요 용도 | 정적 파일 제공, 리버스 프록시 | Java 웹 애플리케이션 실행 |
| 언어 지원 | 다양한 언어 (프록시를 통해) | 주로 Java |
| 성능 | 높은 동시 접속 처리 | Java 애플리케이션 처리에 최적화 |
| 메모리 사용 | 매우 낮음 | 상대적으로 높음 |
| 정적 파일 | 매우 빠름 | 상대적으로 느림 |
| 동적 컨텐츠 | 불가 (프록시 필요) | 가능 |
| 설정 복잡도 | 간단 | 중간 |
| 확장성 | 이벤트 기반으로 뛰어남 | 스레드 기반으로 제한적 |