1. 웹 애플리케이션에서의 요청 처리 흐름
- 사용자가 웹 브라우저에서 요청을 보내면 WAS(Web Application Server) 가 이를 처리.
- 요청이 들어오면 TCP/IP 연결이 이루어지고, 이후 서블릿(Servlet) 이 호출됨.
- 하지만 서블릿은 직접 실행되는 것이 아니라, 스레드(Thread) 가 실행함.
- 즉, 클라이언트 요청 → WAS → 서블릿 실행(스레드) 의 구조로 동작.
2. 스레드(Thread) 개념
- 스레드란?
- 애플리케이션 코드의 실행 단위.
- 자바에서
main
메소드를 실행하면 메인 스레드가 하나 생성되어 실행됨.
- 기본적으로 한 개의 스레드는 한 번에 하나의 코드 라인만 실행 가능.
- 동시 처리를 하려면 여러 개의 스레드가 필요.
3. 단일 스레드에서의 문제점
1) 단일 스레드 기반의 요청 처리
- 한 개의 요청이 들어오면 스레드 하나를 할당하여 서블릿 실행.
- 요청이 처리되고 응답이 완료되면 스레드는 휴식 상태로 전환.
단점:
- 요청이 하나만 들어올 경우 정상 처리 가능하지만,
- 두 번째 요청이 들어오면 첫 번째 요청이 끝날 때까지 기다려야 함.
- 특정 요청이 지연되면 다음 요청도 지연되면서 서비스가 멈추는 문제 발생.
4. 요청마다 새로운 스레드를 생성하는 방식의 문제점
1) 해결 방법: 요청마다 새로운 스레드 생성
- 요청이 들어올 때마다 새로운 스레드를 생성하여 처리.
- 하나의 요청이 지연되어도 다른 요청이 정상적으로 실행됨.
장점:
- 여러 요청을 동시에 처리 가능.
- 하나의 요청이 느려도 다른 요청은 정상 처리 가능.
단점:
- 스레드 생성 비용이 높음.
- 스레드 개수가 많아지면 CPU, 메모리 사용량 증가.
- 무제한으로 생성하면 서버 다운 위험 발생.
- 예) 사용자가 갑자기 몰려들어 수천 개의 스레드가 생성되면 CPU와 메모리가 한계를 넘어 서버가 다운됨.
5. WAS의 최적화: 스레드 풀(Thread Pool) 사용
1) 스레드 풀 개념
- 스레드를 요청마다 새로 만들지 않고, 미리 여러 개를 만들어두고 재사용하는 방식.
- 일정 개수의 스레드를 유지하면서 요청이 들어올 때마다 기존 스레드를 할당하여 처리.
스레드 풀(Thread Pool) 동작 방식
1. 미리 일정 개수(예: 200개)의 스레드를 생성.
2. 요청이 들어오면 스레드 풀에서 유휴 스레드를 할당하여 실행.
3. 요청이 끝나면 스레드를 종료하지 않고 다시 풀에 반납.
4. 만약 스레드 풀이 꽉 차면 요청을 대기하거나 거절.
장점:
1. 스레드 생성 비용 절감 → 요청마다 새로 만들지 않고 재사용.
2. 서버 안정성 향상 → 과도한 스레드 생성으로 인한 서버 다운 방지.
3. 빠른 응답 속도 → 스레드가 미리 생성되어 즉시 사용 가능.
단점:
1. 최대 스레드 개수를 설정해야 함.
2. 너무 낮으면 서비스가 멈추고, 너무 높으면 서버 과부하 발생.
6. 스레드 풀의 한계와 튜닝 방법
1) 적절한 스레드 개수 설정이 중요
최대 스레드 수
를 너무 낮게 설정하면?
- 요청이 많아질 때 처리가 지연되면서 대기 시간이 증가.
- CPU 사용률이 낮아도 요청을 처리하지 못함.
최대 스레드 수
를 너무 높게 설정하면?
- 과도한 동시 요청을 받아들이면서 CPU, 메모리가 과부하.
- 서버가 과부하로 다운될 가능성 증가.
예제) 톰캣(Tomcat) 스레드 풀 설정
<Connector port="8080"
protocol="HTTP/1.1"
maxThreads="200"
minSpareThreads="10"
maxConnections="1000" />
maxThreads=200
: 최대 200개의 스레드 유지.
minSpareThreads=10
: 최소 10개의 유휴 스레드 유지.
maxConnections=1000
: 동시에 1000개의 연결을 받을 수 있음.
7. 실무 적용 및 성능 튜닝
1) 적절한 스레드 개수 찾기
- WAS가 제공하는 기본값(예: Tomcat 200개)이 항상 최적은 아님.
- 애플리케이션의 특성(쿼리 수, 로직 복잡도, 서버 사양)에 따라 다름.
- 최적의 값을 찾으려면 성능 테스트(부하 테스트)를 진행해야 함.
2) 부하 테스트 도구 활용
- 성능 테스트 도구 예시:
- Apache AB (Apache Benchmark)
- JMeter
- NGrinder (네이버 오픈소스 부하 테스트 도구)
- 부하 테스트를 통해 최대 처리 가능한 트래픽을 확인하고 최적의 설정값 적용.
8. WAS의 멀티스레드 지원과 개발자 역할
- WAS가 멀티스레드 환경을 자동으로 처리하므로 개발자가 직접 관리할 필요 없음.
- 개발자는 서블릿 및 비즈니스 로직에 집중하면 됨.
- 멀티스레드 환경에서 주의할 점:
- 싱글톤 객체(서블릿, 스프링 빈)의 멤버 변수는 동시 접근을 고려해야 함.
- 공유 변수 사용 시 동기화 또는 별도의 저장소(redis, DB 등) 활용.
9. 정리
- 단일 스레드 기반의 WAS는 동시 요청 시 성능이 저하됨.
- 요청마다 새로운 스레드를 생성하면 과부하 위험이 있음.
- WAS는 스레드 풀(Thread Pool)을 사용하여 최적화.
- 적절한 스레드 개수를 설정하여 서버 과부하를 방지해야 함.
- 부하 테스트를 통해 최적의 설정값을 찾는 것이 중요.
- 개발자는 멀티스레드를 직접 다룰 필요 없이 비즈니스 로직에 집중 가능.