어플리케이션

Tomcat 쓰레드(Thread) 에 대해 알아보겠습니다.

forward error correction Circle 2025. 2. 17. 08:27
반응형

Ⅰ. Apache Tomcat 이란?

 Java Servlet을 실행하는 웹 애플리케이션 서버로, 요청을 처리하기 위해 쓰레드를 사용합니다. Tomcat은 멀티스레드 모델을 사용하여 동시 요청을 처리하며, 효율적인 리소스 관리를 위해 쓰레드 풀(Thread Pool) 을 운영합니다.

Ⅱ. Tomcat의 쓰레드 모델

Tomcat은 클라이언트 요청을 처리하기 위해 내부적으로 쓰레드를 생성하여 실행합니다. 주요 쓰레드 유형은 다음과 같습니다.

ⅰ) 메인 쓰레드 (Main Thread)
Tomcat 서버가 실행될 때 생성되는 주요 쓰레드입니다.
설정 파일(server.xml)을 읽고, 서버를 시작하거나 종료하는 역할을 합니다.

 

ⅱ) Acceptor Thread
클라이언트의 요청을 감지하고, 이를 처리할 수 있는 Worker Thread에게 전달합니다.
기본적으로 NIO(Non-blocking I/O) 기반의 동작을 수행합니다.

 

ⅲ) Worker Thread (처리용 쓰레드)
요청을 처리하는 실제 작업 쓰레드입니다.
쓰레드 풀(Thread Pool)에서 관리되며, 요청이 들어오면 사용되고 작업이 끝나면 반환됩니다.

Ⅲ. 쓰레드 풀(Thread Pool)

 성능 최적화를 위해 쓰레드 풀(Thread Pool) 을 사용합니다. 새로운 요청이 들어올 때마다 새로운 쓰레드를 생성하는 것이 아니라, 미리 할당된 쓰레드를 재사용하는 방식입니다.

(1) 쓰레드 풀 설정 (server.xml)
Tomcat의 server.xml 파일에서 커넥터(Connector) 설정을 통해 쓰레드 풀의 크기를 조정할 수 있습니다.

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           maxThreads="200"
           minSpareThreads="10"
           acceptCount="100"
           enableLookups="false"
           redirectPort="8443" />

Server.xml 파일 내 설정 설명
maxThreads: 최대 동작할 수 있는 쓰레드 개수 (기본값: 200)
minSpareThreads: 최소 유지되는 쓰레드 개수 (기본값: 10)
acceptCount: 요청 대기열 크기 (요청이 많아 쓰레드가 부족할 때 대기할 수 있는 요청 수)

Ⅳ. Tomcat 쓰레드 동작 방식

 ⅰ. 사용자가 HTTP 요청을 보냄
 ⅱ. Acceptor Thread가 요청을 감지하고 요청 큐(Request Queue) 에 넣음
 ⅲ. 쓰레드 풀이 관리하는 Worker Thread가 요청을 가져가 처리
 ⅳ. 요청이 완료되면 Worker Thread는 다시 쓰레드 풀로 반환됨

Ⅴ. Tomcat 쓰레드 풀의 장점

ⅰ. 성능 최적화: 쓰레드를 미리 생성하여 재사용함으로써 생성/소멸 비용을 줄임
ⅱ. 리소스 효율성: 적절한 maxThreads 설정을 통해 서버 리소스를 효율적으로 사용 가능
ⅲ. 대규모 트래픽 처리 가능: 동시 요청을 효과적으로 분배하여 많은 요청을 처리할 수 있음

Ⅵ. Tomcat 쓰레드 관련 문제 및 해결책

관련 문제 내용 해결책
요청 처리 지연 maxThreads가 너무 낮으면 동시 요청이 많을 때 
대기 시간이 증가할 수 있음.
maxThreads 값을 적절히 증가시켜 성능을 최적화.
쓰레드 부족 현상 
(Thread Starvation)
acceptCount를 초과하는 요청이 들어오면 새로운 요청이 거부됨. acceptCount와 maxThreads 값을 조정하여 대기 요청을 늘릴 수 있음.
메모리 부족
(OutOfMemoryError)
너무 많은 쓰레드를 생성하면 메모리 부족 문제 발생 가능. 서버의 메모리 용량을 고려하여 maxThreads 값을 설정.

 

Ⅶ. Tomcat 쓰레드 사용량

ⅰ. 쓰레드 하나당 CPU 사용량

1. CPU 사용량을 결정하는 요인
작업 유형: 요청이 단순한 정적 페이지 처리인지, 복잡한 연산을 포함하는 동적 페이지 처리인지에 따라 CPU 사용량이 다름.
I/O 대기 시간: 데이터베이스 조회, 네트워크 호출 등 I/O 작업이 많을수록 CPU 사용이 낮아지고 대신 대기 시간이 증가.
멀티코어 활용: Tomcat은 멀티코어 CPU에서 여러 요청을 병렬로 처리함. 쓰레드 개수가 CPU 코어 수보다 많아지면 컨텍스트 스위칭 비용이 증가.

2. 평균적인 CPU 소비량
단순한 정적 HTML 요청: 거의 CPU 사용 없음 (~1-2% 미만)
서블릿 처리 (비즈니스 로직 포함): 요청당 1-5% (CPU 코어 기준)
복잡한 연산 (예: JSON 파싱, 암호화, AI 모델 처리): 요청당 10~50% 이상의 CPU 사용 가능
즉, 쓰레드 하나당 CPU 사용량은 요청의 복잡도에 따라 거의 0%~50% 이상까지 변할 수 있음.


ⅱ. 쓰레드 하나당 메모리 사용량

1. 쓰레드 스택 크기
Java 쓰레드는 각자 스택(Stack) 메모리를 가짐.
Tomcat에서 실행되는 일반적인 쓰레드의 스택 크기는 기본적으로 1MB (64비트 JVM 기준).
-Xss 옵션으로 쓰레드 스택 크기를 조정할 수 있음.
-Xss512k   # 쓰레드당 스택 크기를 512KB로 설정
-Xss2m     # 쓰레드당 스택 크기를 2MB로 설정

2. 힙(Heap) 메모리 사용량
요청 처리 중 생성된 객체는 JVM 힙 메모리(Heap Memory)에 저장됨.
쓰레드 하나가 처리하는 요청의 크기, 내부적으로 할당되는 객체의 개수에 따라 다름.
예를 들어, JSON 파싱이나 문자열 처리 등이 많을 경우 추가적인 힙 메모리 사용 발생.

3. 평균적인 메모리 소비량
기본적인 서블릿 요청: 요청당 약 512KB ~ 5MB 메모리 사용 가능.
데이터베이스 조회 포함: 5MB ~ 20MB (결과 데이터 크기에 따라 다름).
대형 데이터 처리 (예: 대용량 파일, 이미지 처리 등): 50MB 이상.

4. 메모리 사용 예제
예를 들어, maxThreads=200 으로 설정된 Tomcat이 실행될 때, 쓰레드가 메모리를 차지하는 방식:
쓰레드 스택 크기 1MB → 200MB(200 x 1MB)
추가적인 힙 메모리 (요청당 10MB 가정) → 최대 2GB (200 x 10MB)
총 메모리 사용량: 약 2~2.5GB + 기타 GC 오버헤드


ⅲ. 쓰레드 개수 조정 가이드

1. CPU 기반 조정
일반적으로 CPU 코어 개수 × 2~4배 수준으로 maxThreads 설정.
예: 8코어 서버 → maxThreads=32~64 추천.
CPU 사용량이 지속적으로 70~80% 이상이면 쓰레드 개수를 줄이고, 요청 처리 속도를 높이는 방법 고려.

2. 메모리 기반 조정
사용 가능한 JVM 힙 크기(-Xmx 설정 값) 를 기준으로 maxThreads 설정.
예: JVM 힙 메모리 4GB, 요청당 10MB 메모리 사용 → maxThreads=400 이하로 설정.
-Xss 값을 조정하여 쓰레드 스택 크기 조절 가능.

3. 최적화 팁
maxThreads 값을 CPU 코어 수와 메모리 용량에 맞게 조정.
-Xss 및 -Xmx 값을 조절하여 쓰레드 스택과 힙 사용량 최적화.



반응형