스레드 풀
이 무엇이고 자바에서 스레드 풀
을 가지고 어떻게 스레드
를 관리하는지 알아보자
자바 5는 자바 프로그래머가 태스크 제출
과 실행
을 분리할 수 있는 기능을 제공했다.
자바 스레드
는 직접 운영체제 스레드에 접근한다. 운영체제 스레드를 만들고 종료하려면 비싼 비용
을 치러야 한다.
하지만 운영체제의 스레드 숫자는 제한되어있다. 운영체제가 지원하는 스레드 수를 초과해 사용하면 자바 애플리케이션이 예상치 못한 방식으로 크러시
될 수 있으므로 기존 스레드가 실행되는 상태에서 계속 새로운 스레드를 만드는 상황이 일어나지 않도록 주의해야 한다.
위에서 스레드를 그냥 가져다 쓰면 무슨 일이 일어나는지 언급했다. 따라서 이 문제점들을 해결하기 위해서 스레드 풀을 사용해야 한다.
(기본적으로 스프링 부트에서 제공하는 tomcat
은 스레드 풀을 지원한다.)
자바 ExecutorService
는 태스크를 제출하고 나중에 결과를 수집할 수 있는 인터페이스를 제공한다. 프로그램은 newFixedThreadPool
같은 팩토리 메서드
중 하나를 이용해 스레드 풀
을 만들어 사용할 수 있다.
ExecutorService newFixedThreadPool(int nThreads)
위의 메서드는 워커 스레드
라 불리는 nThreads
를 포함하는 ExecutorService
를 만들고 이들을 스레드 풀
에 저장한다.
스레드 풀에서 사용하지 않은 스레드로 제출된 태스크를 먼저 온 순서대로 실행한다. 이들 태스크 실행이 종료되면 이들 스레드를 풀로 반환한다.
하지만 우리는 웹 백엔드 개발자
가 아닌가
위에서 나온 JAVA 5
에서 팩토리 메서드를 사용해가며 스레드 풀을 만들 필요 없다.
아래 코드처럼 yml
에 서버의 스레드 풀을 직접 관리해도 좋고 당연한 소리지만 properties
에서 관리해도 좋다.
server:
tomcat:
threads:
max: 200
min-spare: 10
max-connections: 8192
accept-count: 100
connection-timeout: 20000
port: 8080
위 내용이 무슨 뜻인지 아래에서 더 자세하게 살펴보자.
아래 사진은 스레드 풀에 스레드 200개가 있는 모습이다.
스레드 풀에 스레드가 없는데 계속 요청을 보내면 이미 스레드를 사용하고 있던 reqeust
가 스레드를 반환해 줄 때까지 기다리거나, 거절하는 모습이다.
이 같은 모습은 request
가 스레드를 사용하고 다시 스레드 풀로 반환해야 한다는 것을 의미한다.
스레드 풀의 특징은 다음과 같다
스레드
를 스레드 풀
에 보관
하고 관리
한다.스레드 풀
에 생성 가능한 스레드
의 최대치
를 관리한다.톰캣
은 최대 200개
가 기본 설정이며 변경 가능하다.스레드
를 반납
한다.마지막 특징은 스레드 풀에 스레드가 0개이면 대기하는 request
의 수를 정할 수 있다는 말이다.
스레드 풀
의 궁극적인 장점
은 하드웨어에 맞는 수의 태스크
를 유지함
과 동시에 수 천개
의 태스크(request)
를 스레드 풀
에 아무 오버헤드
없이 제출할 수 있다는 점이다.
WAS
의 주요 튜닝 포인트는 최대 스레드 수
이다.
값을 너무 낮게 설정하면?
동시 요청이 많을 때 서버 리소스는 여유롭지만 클라이언트는 금방 응답이 지연된다.
값을 너무 높게 설정하면?
동시 요청이 많으면 CPU, 메모리 리소스 임계점 초과로 서버가 다운된다.
스레드 풀의 최적의 스레드 수를 고려하고 있다면 nGrider
로 성능 테스트를 해보는 것을 추천한다.