1.WAS와 웹서버의 차이
웹서버 (Web Server)
- 역할: HTTP 요청을 받아서 정적인 리소스를 응답
- 예: HTML, CSS, JS, 이미지, 동영상, 다운로드 파일
- 특징
- 정적 파일 서빙에 최적화(빠르고 가벼움)
- 리버스 프록시 기능(요청을 뒤의 서버로 전달), 로드밸런싱, SSL 종료(HTTPS 처리) 등을 자주 담당
- 예시
- Nginx, Apache HTTP Server, Caddy
WAS (Web Application Server)
- 역할: 웹 애플리케이션을 실행해서 동적인 응답을 생성
- 예: 로그인/회원가입, 게시판 CRUD, 결제 처리, 권한 체크, DB 조회 결과로 HTML/JSON 생성 등
- 특징
- 비즈니스 로직 실행 + DB 연동 + 트랜잭션 + 세션/인증 등 “앱” 기능의 중심
- 보통 프레임워크(Spring, Django 등)가 여기서 돌아감
- 예시
- Java: Tomcat(서블릿 컨테이너), Jetty, Undertow / (더 전통적 의미의 WAS: WebLogic, WebSphere, JBoss/WildFly 등)
- Node.js(Express/Nest)도 “WAS 역할”을 하는 애플리케이션 서버로 보면 됨
* 둘을 같이 쓰는 이유
클라이언트 → 웹서버(Nginx) → WAS(Tomcat/Spring Boot) → DB
웹 :
- 정적 파일은 바로 처리(빠름)
- 동적 요청은 WAS로 전달(리버스 프록시)
- HTTPS, 압축(gzip/br), 캐싱, 로드밸런싱, 보안 헤더 같은 공통 처리 담당
WAS:
- API/비즈니스 로직 처리
- DB 접근, 인증/인가, 트랜잭션 등 핵심 기능 처리
웹서버와 was를 사용해본 경험
1. 웹서버
리액트 npm run dev로 실행한 웹 서버
2. was
세미 프로젝트, 학업중 과제 등 다양한 스프링 부트 프로젝트
톰캣을 활용한 웹 페이지.
* 단 톰캣은 전통적인 was라기보다는 서블릿 컨테이너이며 전통적인 was는 WebLogic/WebSphere/WildFly
2. was와 웨서버가 제공하는 최적화
웹서버가 제공하는 최적화 (Nginx/Apache/Caddy 등)
정리하면 “요청을 싸게 처리하고, 뒤쪽 서버(WAS)를 보호/가볍게” 해줍니다.
- 정적 파일 고속 서빙
- OS 레벨 최적화(예: sendfile)로 파일을 효율적으로 전송
- 정적 파일에 대한 캐시 헤더(ETag, Cache-Control) 설정으로 재요청 줄임
- 동시 접속 처리 효율
- 이벤트 기반/비동기 처리로 커넥션을 가볍게 유지(특히 Nginx)
- Keep-Alive 관리, 대량 연결에 강함
- 압축/전송 최적화
- gzip / brotli 압축으로 트래픽 절감
- HTTP/2(그리고 환경에 따라 HTTP/3)로 다중화/헤더 압축 등
- TLS(HTTPS) 처리 최적화
- TLS 종료(암복호화)를 웹서버가 맡아 WAS 부담 감소
- 리버스 프록시 버퍼링
- 느린 클라이언트에게 응답을 웹서버가 대신 천천히 보내고, WAS는 빨리 반환 가능(특히 업로드/다운로드에서 체감 큼)
- 로드밸런싱/헬스체크
- 여러 WAS 인스턴스로 분산 + 장애 인스턴스 제외
- 보안/안정성 최적화
- Rate limiting, IP 차단, WAF 연계, 요청 크기 제한 등으로 WAS 보호
- 캐싱(선택)
- 자주 조회되는 응답을 웹서버/프록시 레벨에서 캐시(구성에 따라)
WAS가 제공하는 최적화 (Tomcat/Jetty + Spring 등)
정리하면 “코드를 빠르고 안정적으로 실행하고, DB 작업을 효율화”합니다.
- 요청 처리 스레드/큐 관리
- 스레드 풀로 생성/파괴 비용을 줄이고 처리량 안정화
- 백프레셔(큐/최대 동시 처리)로 과부하 시 무너짐 방지
- 세션/인증/인가 처리
- 세션(또는 토큰 검증) 처리 흐름 최적화(필터 체인 등)
- DB 최적화의 핵심: 커넥션 풀
- HikariCP 같은 커넥션 풀로 DB 연결 재사용(성능에 매우 큰 영향)
- 쿼리 실행 최적화
- PreparedStatement 재사용, 배치 처리, 트랜잭션 경계 관리
- ORM(JPA) 사용 시 1차 캐시/지연 로딩 등으로 쿼리 패턴 최적화(잘 쓰면 이득, 잘못 쓰면 N+1 폭탄)
- 애플리케이션 캐싱
- 로컬 캐시(Caffeine), 분산 캐시(Redis) 등으로 DB hit 줄임
- 직렬화/역직렬화 최적화
- JSON 파싱/생성(Jackson) 설정, 페이로드 크기 조절, 압축 연계
- 런타임 최적화
- JVM JIT 컴파일, GC 튜닝(필요 시), 클래스 로딩 최적화 등
- 비동기 처리/스트리밍(선택)
- Async Servlet, WebFlux 같은 모델로 I/O 대기 효율 개선(케이스에 따라)
요약.
- 웹서버 최적화 = “요청/정적/전송/보안/분산”을 싸게 처리해서 WAS를 보호
- WAS 최적화 = “비즈니스 로직/DB/캐시/스레드”를 효율적으로 돌려 응답을 빨리 생성
꼬리질문
1) Tomcat은 웹서버인가요, WAS인가요?
Tomcat은 웹서버라기보단 서블릿 컨테이너이고, 자바 웹 애플리케이션을 실행해서 동적 응답을 만들기 때문에 실무에서는 WAS처럼 사용합니다.
다만 Nginx 같은 웹서버처럼 정적 파일/프록시/캐싱에 특화된 제품과는 역할이 다릅니다.
2) Spring Boot 내장 톰캣(JAR) vs 외부 Tomcat(WAR) 배포 차이는?
- JAR(내장 톰캣): 애플리케이션 안에 서버가 포함돼서 java -jar로 실행 가능, 배포/실행이 단순함
- WAR(외부 톰캣): 톰캣이 별도 설치돼 있고 그 위에 WAR를 올리는 방식, 운영 표준이 그렇게 잡혀있는 조직에서 사용
요즘은 보통 Spring Boot JAR 방식이 더 흔하고, 레거시/기업 환경에선 WAR도 많이 봅니다.
3) Nginx 리버스 프록시를 두면 요청 흐름은 어떻게 되나요?
클라이언트 요청을 Nginx가 먼저 받고,
- /, /assets 같은 정적 경로는 Nginx가 직접 서빙
- /api 같은 동적 요청만 WAS(Spring)로 프록시해서 전달합니다.
이렇게 분리하면 WAS는 로직 처리에 집중하고, 정적/연결 처리는 웹서버가 맡아서 전체 성능이 안정적입니다.
4) 정적 파일 캐싱 전략은 어떻게 잡나요?
기본 전략은:
- 파일명에 해시가 붙는 빌드 산출물(app.abc123.js)은 Cache-Control: max-age 길게 + immutable로 강하게 캐싱
- index.html처럼 엔트리 파일은 짧게 캐싱하거나 no-cache로 두고, 새 배포 시 최신 번들을 가리키게 합니다.
ETag를 쓰면 변경 시점 판단도 깔끔합니다.
5) HTTPS(SSL 종료)는 어디서 처리하는 게 좋나요?
대부분은 웹서버(Nginx)나 로드밸런서에서 SSL 종료를 합니다.
이유는 TLS 처리를 앞단에서 통합하면 WAS 부담이 줄고, 인증서 관리/갱신도 한 곳에서 관리돼 운영이 편합니다.
내부망 구간은 HTTP로 두거나, 보안 요구가 높으면 내부도 TLS를 유지합니다.
6) WAS 성능 튜닝은 뭘 만져봤나요?
핵심은 “WAS 자체”보다 DB 접근 최적화가 체감이 큽니다.
- HikariCP 커넥션 풀(max pool size, timeout)
- Tomcat 스레드 풀(max threads, accept queue)
- 요청 타임아웃/리트라이 정책
그리고 실제로는 슬로우 쿼리/병목 로그를 보고 조정하는 게 정석입니다.
7) N+1 문제를 겪어봤다면 어떻게 발견하고 해결하나요?
발견: 목록 조회에서 쿼리가 1번이 아니라 엔티티 개수만큼 추가로 나가는지 로그로 확인합니다.
해결: 상황에 따라
- fetch join으로 한 번에 가져오거나
- DTO projection으로 필요한 필드만 조회하거나
- @EntityGraph, batch size 설정으로 완화합니다.
핵심은 “조회 목적에 맞게 쿼리 형태를 바꾸는 것”입니다.
8) 세션 기반 vs JWT 기반 인증의 장단점은?
- 세션: 서버가 상태를 가짐(상태 기반). 구현이 직관적이지만 수평 확장 시 세션 공유가 필요합니다.
- JWT: 토큰에 인증 정보를 담아 무상태(Stateless) 로 확장에 유리합니다. 대신 토큰 탈취/폐기(로그아웃) 처리, 만료/리프레시 설계가 중요합니다.
실무는 서비스 성격과 확장 요구에 따라 선택합니다.
9) WAS를 수평 확장하면 세션은 어떻게 처리하나요?
대표 방법은 3가지입니다.
- Sticky Session: 같은 사용자를 같은 서버로 붙임(간단하지만 장애/확장 유연성 떨어짐)
- 세션 스토리지 외부화: Redis 같은 곳에 세션 저장(Spring Session Redis 등)
- JWT로 무상태화: 서버에 세션을 두지 않음
확장성과 운영 안정성은 보통 2)나 3)이 더 좋습니다.
10) 운영 배포 구조를 설계한다면 어떤 구성이 현실적인가요?
대표적으로는:
- 정적 프론트: CDN/정적 호스팅(또는 Nginx)
- 백엔드 API: Spring Boot(WAS)
- 앞단: Nginx 또는 로드밸런서(HTTPS 종료, 라우팅, 보안)
- 데이터: DB + 필요하면 Redis(캐시/세션)
이 구조가 성능/보안/확장성 밸런스가 좋아서 가장 흔합니다.
'Daily Dev Q&A' 카테고리의 다른 글
| JVM (0) | 2026.01.18 |
|---|---|
| application context (0) | 2026.01.16 |
| Garbage Collection (0) | 2026.01.07 |
| 자바 가상 머신 (0) | 2026.01.07 |
| spring의 예외처리방식 (0) | 2025.12.30 |