WAS vs Web Server 완벽 비교: Nginx 동작 원리부터 리버스 프록시, Tomcat 연동까지

WAS vs Web Server 완벽 비교: Nginx 동작 원리부터 리버스 프록시, Tomcat 연동까지

“Web Server와 WAS의 차이가 뭔가요?”, “Nginx를 왜 앞에 두나요?”, “Spring Boot 내장 Tomcat만 쓰면 안 되나요?” — Web Server와 WAS의 역할 분리는 백엔드 배포 아키텍처의 기본이다.


1. Web Server란

1.1 역할과 특징

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌─────────────────────────────────────────────────────────────────────┐
│                    Web Server 역할                                    │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Web Server = 정적 콘텐츠를 응답하는 서버                           │
│                                                                     │
│  처리 대상:                                                         │
│  • HTML, CSS, JavaScript 파일                                       │
│  • 이미지, 동영상, 폰트 등 정적 리소스                              │
│                                                                     │
│  주요 기능:                                                         │
│  • HTTP 요청 수신 및 정적 파일 응답                                 │
│  • 리버스 프록시 (요청을 WAS에 전달)                                │
│  • 로드 밸런싱 (여러 WAS에 분산)                                    │
│  • SSL/TLS 종료 (HTTPS 처리)                                       │
│  • 캐싱 (정적 파일 캐시)                                            │
│  • 요청 필터링, 접근 제어                                           │
│                                                                     │
│  대표: Nginx, Apache HTTP Server                                    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

2. WAS (Web Application Server)란

2.1 역할과 특징

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
┌─────────────────────────────────────────────────────────────────────┐
│                       WAS 역할                                       │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  WAS = 동적 콘텐츠를 생성하는 서버                                  │
│                                                                     │
│  처리 대상:                                                         │
│  • 비즈니스 로직 실행                                               │
│  • DB 조회/수정                                                     │
│  • API 응답 생성 (JSON 등)                                          │
│  • 인증/인가 처리                                                   │
│                                                                     │
│  주요 기능:                                                         │
│  • 서블릿 컨테이너 (Servlet 실행 환경)                              │
│  • JSP/Thymeleaf 등 동적 페이지 렌더링                              │
│  • 트랜잭션 관리                                                    │
│  • 커넥션 풀 관리                                                   │
│  • 멀티스레드 요청 처리                                              │
│                                                                     │
│  대표: Tomcat, Jetty, Undertow                                      │
│                                                                     │
│  ※ WAS는 Web Server 기능도 포함 (정적 파일 서빙 가능)              │
│     → 하지만 정적 파일 처리 성능은 전용 Web Server가 월등히 빠름    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

3. Web Server vs WAS 비교

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌─────────────────────────────────────────────────────────────────────┐
│              Web Server vs WAS 비교                                   │
├──────────────────┬──────────────────────┬────────────────────────────┤
│ 항목             │ Web Server           │ WAS                        │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 처리 대상        │ 정적 콘텐츠          │ 동적 콘텐츠 (+ 정적)       │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 비즈니스 로직    │ 없음                 │ 있음 (서블릿, 스프링)      │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ DB 접근          │ 불가                 │ 가능                       │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 프로토콜         │ HTTP/HTTPS           │ HTTP + 서블릿 스펙         │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 동시 처리        │ 이벤트 기반 (비동기) │ 스레드 풀 기반             │
│                  │ → 수만 동시 연결     │ → 수백~수천 스레드         │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 리소스 사용      │ 가벼움 (메모리 적음) │ 무거움 (JVM 메모리)        │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 대표             │ Nginx, Apache        │ Tomcat, Jetty, Undertow    │
└──────────────────┴──────────────────────┴────────────────────────────┘

4. 왜 Web Server를 WAS 앞에 두는가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌─────────────────────────────────────────────────────────────────────┐
│              Web Server + WAS 분리 이유                               │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ① 정적/동적 처리 분리 → 성능 향상                                  │
│     • 이미지, CSS, JS → Nginx가 직접 응답 (WAS 부하 감소)          │
│     • API 요청 → WAS로 전달                                        │
│                                                                     │
│  ② 리버스 프록시 → 보안 강화                                        │
│     • WAS의 실제 IP/포트를 외부에 노출하지 않음                     │
│     • WAS 에러 페이지 대신 커스텀 에러 응답                         │
│                                                                     │
│  ③ 로드 밸런싱 → 확장성                                             │
│     • 여러 WAS에 요청 분산                                          │
│     • 한 WAS 장애 시 다른 WAS로 자동 전환                          │
│                                                                     │
│  ④ SSL 종료 (SSL Termination)                                       │
│     • HTTPS 암호화/복호화를 Nginx에서 처리                          │
│     • WAS는 HTTP로만 통신 → 연산 부담 감소                         │
│                                                                     │
│  ⑤ 캐싱                                                             │
│     • 자주 요청되는 응답을 Nginx에서 캐시                           │
│     • WAS 호출 없이 즉시 응답                                       │
│                                                                     │
│  ⑥ 무중단 배포                                                      │
│     • WAS 재시작 중에도 Nginx가 요청을 다른 WAS로 전달             │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

아키텍처 구성도

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌─────────────────────────────────────────────────────────────────────┐
│                    실무 배포 구조                                     │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  클라이언트 (브라우저)                                               │
│       │                                                             │
│       │ HTTPS (443)                                                 │
│       ▼                                                             │
│  ┌──────────────────────────────────────────────────────┐           │
│  │                    Nginx                              │           │
│  │  • SSL 종료                                           │           │
│  │  • 정적 파일 직접 응답 (/static, /images)             │           │
│  │  • API 요청은 WAS로 프록시                            │           │
│  └────┬──────────────────────────────────┬──────────────┘           │
│       │ HTTP (8080)                      │ HTTP (8081)              │
│       ▼                                  ▼                          │
│  ┌─────────────┐                 ┌─────────────┐                    │
│  │  Tomcat #1  │                 │  Tomcat #2  │                    │
│  │  (WAS)      │                 │  (WAS)      │                    │
│  │  Spring Boot│                 │  Spring Boot│                    │
│  └──────┬──────┘                 └──────┬──────┘                    │
│         └──────────────┬────────────────┘                           │
│                        ▼                                            │
│                 ┌────────────┐                                      │
│                 │   MySQL    │                                      │
│                 └────────────┘                                      │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

5. Nginx 동작 원리

5.1 이벤트 기반 비동기 아키텍처

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
┌─────────────────────────────────────────────────────────────────────┐
│              Apache vs Nginx 처리 모델                                │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  [Apache - 프로세스/스레드 기반]                                    │
│                                                                     │
│  요청 1 → 스레드 1 (처리 중... 대기... 응답)                       │
│  요청 2 → 스레드 2 (처리 중... 대기... 응답)                       │
│  요청 3 → 스레드 3 (처리 중... 대기... 응답)                       │
│  요청 4 → 대기... (스레드 부족!)                                   │
│                                                                     │
│  → 동시 연결 수 = 스레드 수에 제한                                  │
│  → C10K 문제 (1만 동시 접속 시 성능 급락)                          │
│                                                                     │
│  ─────────────────────────────────────────────────                  │
│                                                                     │
│  [Nginx - 이벤트 기반 비동기]                                       │
│                                                                     │
│  ┌───── Master Process ─────┐                                      │
│  │  • 설정 파일 로드         │                                      │
│  │  • Worker Process 관리    │                                      │
│  └─────────┬─────────────────┘                                      │
│            │                                                        │
│  ┌─────────┴──────────────────────────────┐                         │
│  │          Worker Process (1개)          │                          │
│  │                                        │                          │
│  │  Event Loop (단일 스레드)              │                          │
│  │  ┌─────────────────────────────────┐  │                          │
│  │  │ 요청 1 → 비동기 I/O 등록       │  │                          │
│  │  │ 요청 2 → 비동기 I/O 등록       │  │                          │
│  │  │ 요청 3 → 비동기 I/O 등록       │  │                          │
│  │  │ ...                             │  │                          │
│  │  │ 요청 1 완료 이벤트 → 응답      │  │                          │
│  │  │ 요청 3 완료 이벤트 → 응답      │  │                          │
│  │  └─────────────────────────────────┘  │                          │
│  └────────────────────────────────────────┘                         │
│                                                                     │
│  → 적은 리소스로 수만 동시 연결 처리                                │
│  → Worker 수 = CPU 코어 수 (보통 auto)                              │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

5.2 Nginx vs Apache 비교

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌─────────────────────────────────────────────────────────────────────┐
│                Nginx vs Apache                                       │
├──────────────────┬──────────────────────┬────────────────────────────┤
│ 항목             │ Nginx                │ Apache                     │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 처리 모델        │ 이벤트 기반 (비동기) │ 프로세스/스레드 기반       │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 동시 처리 성능   │ 매우 높음            │ 보통 (C10K 문제)           │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 메모리 사용량    │ 적음 (고정적)        │ 많음 (연결당 증가)         │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 정적 파일 성능   │ 매우 빠름            │ 빠름                       │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 설정 방식        │ 선언적 (nginx.conf)  │ .htaccess 지원 (유연)      │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 모듈 확장        │ 컴파일 시 추가       │ 런타임 동적 로드 가능      │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 리버스 프록시    │ 네이티브 지원 (강력) │ mod_proxy (보통)           │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 시장 점유율      │ 1위 (현재)           │ 과거 1위 → 감소 추세       │
└──────────────────┴──────────────────────┴────────────────────────────┘

6. Nginx 주요 설정

6.1 리버스 프록시 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# /etc/nginx/conf.d/app.conf

upstream backend {
    server 127.0.0.1:8080;  # Tomcat #1
    server 127.0.0.1:8081;  # Tomcat #2
}

server {
    listen 80;
    server_name example.com;

    # HTTP → HTTPS 리다이렉트
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com;

    # SSL 인증서
    ssl_certificate     /etc/ssl/certs/example.crt;
    ssl_certificate_key /etc/ssl/private/example.key;

    # 정적 파일 직접 서빙
    location /static/ {
        alias /var/www/static/;
        expires 30d;                # 30일 캐시
        add_header Cache-Control "public";
    }

    # API 요청 → WAS로 프록시
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 커스텀 에러 페이지
    error_page 502 503 504 /50x.html;
    location = /50x.html {
        root /var/www/error;
    }
}

6.2 로드 밸런싱 전략

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────────────────────────────────────────────────────────────┐
│               Nginx 로드 밸런싱 방식                                 │
├──────────────────────┬──────────────────────────────────────────────┤
│ 방식                 │ 설명                                         │
├──────────────────────┼──────────────────────────────────────────────┤
│ Round Robin (기본)   │ 순서대로 돌아가며 분배                       │
│                      │ upstream { server A; server B; }             │
├──────────────────────┼──────────────────────────────────────────────┤
│ Least Connections    │ 현재 연결 수가 가장 적은 서버로              │
│                      │ upstream { least_conn; ... }                 │
├──────────────────────┼──────────────────────────────────────────────┤
│ IP Hash              │ 클라이언트 IP 기반 고정 분배                 │
│                      │ → 세션 유지 필요 시 사용                     │
│                      │ upstream { ip_hash; ... }                    │
├──────────────────────┼──────────────────────────────────────────────┤
│ Weighted             │ 서버 성능에 따라 가중치 설정                 │
│                      │ server A weight=3; server B weight=1;       │
└──────────────────────┴──────────────────────────────────────────────┘

7. Spring Boot 내장 Tomcat

7.1 내장 vs 외장 Tomcat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────────────────────────────────────────────────────────────┐
│           내장 Tomcat vs 외장 Tomcat                                  │
├──────────────────┬──────────────────────┬────────────────────────────┤
│ 항목             │ 내장 Tomcat          │ 외장 Tomcat                │
│                  │ (Spring Boot 기본)   │ (전통 방식)                │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 배포 형태        │ JAR (실행 가능)      │ WAR → Tomcat에 배포        │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 실행 방법        │ java -jar app.jar    │ Tomcat 기동 → WAR 배치     │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 설정             │ application.yml      │ server.xml, context.xml    │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 운영 편의성      │ 높음 (단일 프로세스) │ 낮음 (별도 관리 필요)      │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 여러 앱 배포     │ 앱당 별도 프로세스   │ 하나의 Tomcat에 여러 앱    │
├──────────────────┼──────────────────────┼────────────────────────────┤
│ 현재 트렌드      │ 주류 (MSA, Docker)   │ 레거시 환경에서 사용       │
└──────────────────┴──────────────────────┴────────────────────────────┘

7.2 그래도 Nginx가 필요한 이유

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌─────────────────────────────────────────────────────────────────────┐
│       Spring Boot 내장 Tomcat만 쓰면 안 되나?                        │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  내장 Tomcat만으로도 동작하지만, 운영 환경에서는 부족하다.          │
│                                                                     │
│  Nginx 없이 Tomcat만 사용 시 문제:                                  │
│                                                                     │
│  ❌ 정적 파일을 WAS가 처리 → 불필요한 리소스 낭비                   │
│  ❌ SSL 처리를 WAS가 담당 → CPU 부담                                │
│  ❌ 로드 밸런싱 불가 → 단일 서버 의존                               │
│  ❌ WAS 재시작 = 서비스 중단                                        │
│  ❌ DDoS 등 외부 공격에 WAS 직접 노출                               │
│                                                                     │
│  Nginx + 내장 Tomcat 조합이 현재 실무 표준:                         │
│                                                                     │
│  ✅ Nginx: SSL 종료, 정적 파일, 로드밸런싱, 보안                    │
│  ✅ Tomcat: 비즈니스 로직에만 집중                                   │
│                                                                     │
│  소규모 / 개발 환경 → 내장 Tomcat만으로 충분                        │
│  운영 환경 → Nginx + Tomcat (또는 ALB + Tomcat)                    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

8. 무중단 배포와 Nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌─────────────────────────────────────────────────────────────────────┐
│            Nginx를 활용한 무중단 배포 (Blue-Green)                    │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  [STEP 1] 현재 Blue(8080)가 서비스 중                               │
│                                                                     │
│  Nginx ──→ Blue  (8080) ✅ 서비스 중                               │
│             Green (8081) ⬜ 대기                                    │
│                                                                     │
│  [STEP 2] 새 버전을 Green에 배포                                    │
│                                                                     │
│  Nginx ──→ Blue  (8080) ✅ 서비스 중                               │
│             Green (8081) 🔄 새 버전 배포 + 헬스 체크                │
│                                                                     │
│  [STEP 3] Nginx 설정 변경 후 reload                                │
│                                                                     │
│  Nginx ──→ Green (8081) ✅ 새 버전 서비스                          │
│             Blue  (8080) ⬜ 이전 버전 (롤백 대기)                   │
│                                                                     │
│  # nginx -s reload → 기존 연결 유지하면서 설정 변경                │
│  # 연결 중인 요청은 끝날 때까지 기존 서버에서 처리                  │
│  # → 다운타임 제로                                                  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

면접에서 자주 묻는 질문

Q1. Web Server와 WAS의 차이는?

Web Server는 정적 콘텐츠(HTML, CSS, 이미지)를 응답하는 서버이고, WAS는 비즈니스 로직을 실행하여 동적 콘텐츠를 생성하는 서버입니다. WAS는 서블릿 컨테이너를 포함하여 DB 접근, 트랜잭션 관리 등을 수행합니다. Nginx가 대표적인 Web Server, Tomcat이 대표적인 WAS입니다.

Q2. Nginx를 WAS 앞에 두는 이유는?

리버스 프록시로 WAS를 외부에 노출하지 않아 보안이 강화되고, SSL 종료를 Nginx에서 처리해 WAS의 CPU 부담을 줄입니다. 정적 파일은 Nginx가 직접 응답해 WAS 부하를 감소시키며, 로드 밸런싱으로 여러 WAS에 요청을 분산합니다. 또한 WAS 재시작 시에도 Nginx가 다른 WAS로 요청을 전달하여 무중단 배포가 가능합니다.

Q3. Nginx가 높은 동시 처리를 할 수 있는 이유는?

Nginx는 이벤트 기반 비동기 아키텍처를 사용합니다. 요청마다 스레드를 생성하는 Apache와 달리, 소수의 Worker Process가 Event Loop로 수만 개의 연결을 비동기로 처리합니다. I/O 대기 시간에 다른 요청을 처리하므로, 적은 메모리로 높은 동시 처리가 가능합니다.

Q4. 리버스 프록시란?

클라이언트의 요청을 받아 내부 서버(WAS)에 대신 전달하고 응답을 반환하는 프록시입니다. 클라이언트는 실제 WAS의 존재를 모릅니다. 보안(WAS 은닉), 로드밸런싱, SSL 처리, 캐싱 등의 역할을 수행합니다. 포워드 프록시가 클라이언트를 대리하는 것과 반대로, 리버스 프록시는 서버를 대리합니다.

Q5. Spring Boot 내장 Tomcat만 쓰면 안 되나요?

개발/소규모 환경에서는 충분하지만, 운영 환경에서는 한계가 있습니다. 정적 파일 처리에 WAS 리소스를 사용하게 되고, SSL을 WAS가 처리해야 하며, 로드밸런싱이 불가능하고, WAS 재시작 시 서비스가 중단됩니다. 따라서 운영에서는 Nginx(또는 ALB) + 내장 Tomcat 조합을 사용합니다.

Q6. Apache와 Nginx의 차이는?

Apache는 프로세스/스레드 기반으로 요청마다 스레드를 할당하여 처리합니다. 동시 연결이 많아지면 메모리 사용량이 급증합니다(C10K 문제). Nginx는 이벤트 기반 비동기로 소수 Worker가 수만 연결을 처리합니다. 현재는 Nginx가 점유율 1위이며, 리버스 프록시 성능이 특히 뛰어납니다. Apache는 .htaccess를 통한 디렉토리별 설정이 유연한 장점이 있습니다.

Q7. Nginx 로드 밸런싱 방식에는 무엇이 있나요?

Round Robin(기본, 순서대로 분배), Least Connections(현재 연결이 가장 적은 서버로), IP Hash(클라이언트 IP 기반 고정 분배, 세션 유지에 유용), Weighted(서버 성능에 따라 가중치 설정)가 있습니다. 일반적으로 Round Robin이나 Least Connections을 사용하고, 세션 고정이 필요하면 IP Hash를 사용합니다.


핵심 정리: Web Server(Nginx)는 정적 파일 서빙, 리버스 프록시, SSL 종료, 로드밸런싱을 담당하고, WAS(Tomcat)는 비즈니스 로직 실행에 집중한다. 운영 환경에서는 Nginx + Spring Boot(내장 Tomcat) 조합이 표준이며, Nginx의 이벤트 기반 비동기 아키텍처가 높은 동시 처리의 핵심이다.