Search
Duplicate
📒

[Spring Study] 02-3. Servlet 멀티 쓰레드

상태
완료
수업
Spring Study
주제
Servlet
연관 노트
3 more properties
참고

Servlet과 멀티 쓰레드

NOTE
Servlet ContainerServlet을 싱글톤으로 관리하지만, 멀티 쓰레드 방식으로 동작하여 여러 클라이언트의 요청을 처리할 수 있다. 싱글톤의 경우 멀티 쓰레드 방식으로 쓰기 어려울텐데 어떻게 구현하고 있을까?
Servlet Container는 클라이언트에서 요청이 오면 웹 애플리케이션 서버(WAS)에서 쓰레드 1개를 할당해서 요청을 처리하도록 한다.
1 요청 = 1 쓰레드
하지만 HTTP의 요청은 동시에 여러번 올 수 있다. Servlet 컨테이너는 이러한 동시 요청을 처리하기 위해 멀티 쓰레드를 사용한다.
1작업 = 1쓰레드를 위해 쓰레드를 새로 생성한다!
Servlet Container는 요청을 처리할 쓰레드를 할당하며, 쓰레드는 Servletservice()를 호출해서 요청을 처리합니다.
하지만 쓰레드는 생성 비용이 크며, 위와 같이 요청마다 쓰레드를 생성하고, 제거하면 요청수가 많아질수록 쓰레드가 불필요하게 생성되고 삭제되는 오버헤드를 겪을 수 있습니다.

쓰레드 풀

NOTE
쓰레드 풀은 성능과 자원 관리 최적화를 위해 사용되며, 미리 일정 수의 쓰레드를 생성하여 대기시키고, 요청이 들어오면 사용 가능한 쓰레드를 할당하여 처리합니다.
쓰레드 풀
쓰레드 풀을 통해서 매번 새로운 쓰레드를 생성하지 않아도 됩니다.
쓰레드 풀은 쓰레드의 최대 수를 제한하여, 시스템 자원이 고갈되지 않도록 할 수 있습니다.

쓰레드 풀의 구성요소

쓰레드 풀 크기: 유지할 수 있는 쓰레드의 최소 및 최대 개수를 설정합니다.
대기 큐: 모든 쓰레드가 바쁠 때 요청이 대기하는 큐입니다. 쓰레드가 사용 가능해지면 대기 중인 요청이 처리됩니다.
거부 정책: 쓰레드 풀과 대기 큐가 모두 가득찼을 때 요청을 어떻게 처리할지 결정하는 정책입니다. 요청을 거부하거나 대기시키는 방법이 있습니다.
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" maxThreads="200" minSpareThreads="10" acceptCount="100" maxConnections="500" />
XML
복사
Tomcat - server.xml에서 쓰레드 풀을 설정
@Configuration @EnableAsync // 비동기 처리 활성화 public class AsyncConfig { @Bean(name = "taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); // 기본적으로 유지할 쓰레드 수 executor.setMaxPoolSize(10); // 최대 쓰레드 수 executor.setQueueCapacity(25); // 큐의 크기 executor.setThreadNamePrefix("Async-"); // 쓰레드 이름 접두사 executor.initialize(); return executor; } }
Java
복사
Spring - 쓰레드 풀 설정
@Service public class AsyncService { @Async("taskExecutor") public void executeAsyncTask() { System.out.println("Execute method asynchronously - " + Thread.currentThread().getName()); try { // 비동기 작업 시뮬레이션 Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }
Java
복사
비동기 작업

WAS 튜닝

WAS의 주요 튜닝 포인트는 최대 쓰레드의 개수이다
값이 너무 낮다?
동시 요청이 많으면 클라이언트는 금방 응답 지연이 됨
최소 50%는 사용하고 평균 70%는 사용해야 함
값이 너무 높다?
동시 요청이 많으면, CPU/메모리 리소스 임계점 초과로 서버가 다운됨
즉 한계 범위를 모르기에 너무 높으면 서버가 다운된다
쓰레드 풀의 적정 숫자
애플리케이션의 복잡도, CPU 메모리, IO 리소스 상황에 따라 모두 다르다
적절한 쓰레드 개수 = 사용 가능한 코어 * (1+대기시간 / 서비스 시간) → 예시

WAS 튜닝

NOTE
WAS를 효율적으로 운영하기 위해서는 적절한 쓰레드 수를 설정해야 하며 이를 위해 여러가지 요소를 고려할 수 있습니다.
WAS의 주요 튜닝 포인트는 최대 쓰레드의 개수이며 다음과 같은 상황이 발생한다.
값이 너무 낮다?
동시 요청이 많으면 클라이언트는 금방 응답 지연이 됨
최소 50%는 사용하고 평균 70%는 사용해야 함
값이 너무 높다?
동시 요청이 많으면, CPU/메모리 리소스 임계점 초과로 서버가 다운됨
즉 한계 범위를 모르기에 너무 높으면 서버가 다운된다

적절한 쓰레드 개수 공식

적절한 쓰레드 수를 계산하기 위한 공식은 다음과 같습니다:
적절한 쓰레드 개수 = 사용 가능한 코어 수 * (1 + 대기 시간 / 서비스 시간)
Java
복사
정확한 공식이 아닌 대략적인 계산
사용 가능한 코어 수: 서버의 물리적 코어 수입니다. 예를 들어, 8코어 CPU가 있는 서버라면 이 값은 8이 됩니다.
대기 시간: I/O 작업이나 다른 자원을 기다리는 데 소요되는 시간입니다.
서비스 시간: 실제로 요청을 처리하는 데 소요되는 시간입니다.