적정한 쓰레드 수를 찾아보자

김수환·2025년 7월 13일

was 구현기

목록 보기
2/10

개요

WAS ThreadPool 크기, Docker CPU 제한, JMeter 요청 쓰레드 수의 조합에 따라 WAS 성능 분석

도구

- WAS: 직접 만든 서버(`THREAD_POOL_SIZE` 설정)
- Docker: `--cpus` 옵션으로 CPU 코어 수 제한
- JMeter: 동시 사용자 수 (`JMeterThreads`) × 반복 수 (`LOOPS=10`) 설정

측정 지표

- `AvgElapsed`: 평균 응답시간 (ms)
- `MaxElapsed`: 최대 응답시간 (ms)
- `AvgLatency`: 실제 서버 처리 시간 (ms)
- `AvgConnect`: 커넥션 성립까지의 시간 (ms)
- `SuccessRate`: 요청 성공률

테스트 환경

설정 항목
ThreadPool10, 50, 100
Docker 제한 CPU1, 2, 4
JMeter 쓰레드 수10, 50, 100 (× 10회 반복)

총 27개 경우의 테스트 수행, 각 조합당 100개 요청


결과 요약

  • 모든 조합에서 실패 없음 (SuccessRate = 100%)
  • CPU의 코어수 보다ThreadPool의 영향이 큼
  • ThreadPool 50 구성에서 안정적인 성능을 보임
  • ThreadPool 100은 일부 조합에서 MaxElapsed가 급등 → 오히려 비효율

결과 분석

ThreadPool = 10인 경우

CPUJMeterThreadsAvgElapsedMaxElapsedAvgLatency
1105.54 ms183.05.40 ms
1502.67 ms19.0 ms2.60 ms
11002.31 ms17.0 ms2.22 ms
2104.08 ms121.0 ms3.92 ms
2502.40 ms17.0 ms2.27 ms

CPU 1 제한 조건에서도 요청 수 증가에 잘 대응함
그러나 MaxElapsed가 높아지는 경우가 존재 → 부하 스파이크에 취약


CPU = 1인 경우

ThreadPoolJMeterThreadsAvgElapsedP95ElapsedMaxElapsed
10105.54 ms6.05 ms183.0 ms
50101.51 ms2.0 ms3.0 ms
100104.64 ms6.05 ms158.0 ms

ThreadPool 50에서 가장 빠르고 안정적
ThreadPool 100은 성능 하락 및 최대 응답시간 급등


고부하 조건 (동시 요청 수 = 100)

ThreadPoolCPUAvgElapsedMaxElapsedAvgLatency
1012.31 ms17.0 ms2.22 ms
5012.71 ms27.0 ms2.62 ms
10014.64 ms158.0 ms4.46 ms

ThreadPool 100은 컨텍스트 스위칭 비용 증가로 지연 발생
ThreadPool 50이 평균/최대 응답시간 모두에서 가장 안정적


결론

  • ThreadPool 100은 과도한 스레드 생성으로 성능이 저하된다.
  • CPU 리소스보다 ThreadPool 조정이 우선 고려 요소인 것 같다.

코어 수를 늘렸는데 왜 성능이 떨어지지?

  • 아마도 멀티스레드 환경에 대한 성능을 제대로 생각하지 않고 설계한 것 같다.
  • 공유자원에 대한 접근, Lock 등을 고려하지 않고 설계해서 문제가 있다.
  • 특히, 정적 파일 처리나 요청 경로 처리 등에서 동기화되지 않은 코드가 공통 자원을 참조하거나, GC 부하가 커졌을 가능성도 있다.

개선 방향

물론 모두 예측일 뿐이므로 명확한 원인 분석이 필요하다.

  • ThreadPool 크기에 따른 TPS/Latency 변화 로그를 수집하고 정리하기
  • 정적 파일 처리/경로 파싱 등의 공통 로직에서 공유 자원 여부 및 동기화 필요성 확인하기
  • GC 로그를 활성화하고 메모리 할당 및 GC 시간 확인해보기
profile
hello human

0개의 댓글