01. 동시 요청 - 멀티 쓰레드
01-1. 쓰레드
- 애플리케이션 코드를 하나하나 순차적으로 실행하는 것은 쓰레드
- 자바 메인 메서드 실행 → main 이라는 이름의 쓰레드 실행됨
- 쓰레드가 없다면 자바 애플리케이션 실행 불가능
- 쓰레드는 한 번에 하나의 코드 라인만 수행
- 동시 처리가 필요하면 쓰레드를 추가로 생성
01-2. 단일 요청 쓰레드 하나 사용
- WAS 내의 쓰레드는 현재 요청을 받지 않기에 휴식 단계
- Client 요청 시 연결(Connection)이 수행되고 해당 연결에 쓰레드가 할당된다
- 이렇게 연결된 쓰레드가 서블릿(Servlet)을 호출한다
- 요청 처리를 다 하면 Client에게 응답(Response)을 하고 쓰레드는 다시 휴식에 들어간다
01-3. 다중 요청 쓰레드 하나 사용
- Client 01번이 WAS에 요청을 수행하고 해당 요청이 Thread에 연결된다
- 서블릿(Servlet)이 해당 요청을 바로 처리하면 좋겠지만 현재 처리 지연이 발생한 상황이다
- 이 때 다음과 같이 Client 02번이 요청을 수행한다
- 현재 Client 02번은 Client 01번의 요청이 끝나지 않았기 때문에 대기 상태 에 있는 상황이다
- 위 같은 경우 Client 01번의 요청 종료를 계속 기다려야 하기 때문에 둘 다 disconnected 될 확률이 높다
어떻게 문제를 해결해야 할까? “답은 스레드를 하나 더 생성하면 된다” 이다.
- 위에서 말했다시피 Client 02번은 Client 01번의 요청 여부와 상관 없이 동작 한다
- 즉, 새로운 쓰레드(Thread)가 생성이 되고 해당 쓰레드(Thread)를 통해 Servlet을 호출한다
01-4. 요청 마다 쓰레드 생성의 장단점
- 장점
- 동시 요청 처리 가능
- 리소스(CPU, Memory)가 허용할 때까지 처리 가능
- 하나의 쓰레드가 지연 되어도 나머지 쓰레드 정상 동작
- 단점
- 쓰레드 생성 비용은 상당히 비쌈
- 고객 요청마다 쓰레드 생성하면 응답 속도가 느려짐
- 쓰레드 생성 시 CPU를 많이 쓴다
- 쓰레드는 컨텍스트 스위칭 비용 발생
- 쓰레드 생성에 제한이 없음
- 고객 요청이 너무 많이 오면 CPU, Memory 임계점 넘어서 서버 뻗을 수 있음
- 쓰레드 생성 비용은 상당히 비쌈
작년에 부하테스트를 그렇게 했음에도 불구하고 ECS의 CPU, Memory를 잘못 산정하여
ECS가 죽은 경험이 있었다… 꼭 많은 쓰레드를 사용하는 것이 좋은 것만은 아닌 것 같다…
01-5. WAS는 내부적으로 쓰레드 풀을 갖는다
쓰레드풀은 요청마다 쓰레드를 생성하는 것은 비효율적이기에 사용이 된다.
- WAS 기본적으로 내부에 Thread Pool을 가지고 있음
- Client 01이 요청을 하게 되면 해당 TCP/IP 연결이 Thread Pool에 Thread(쓰레드)를 요청한다
- 또 Client 02이 요청을 하여 Thtread Pool에 Thread(쓰레드)를 요청한다
- Client 01, 02번의 요청을 다 처리하면 다시 Thtread Pool에 Thread를 반환 한다
- 검색 API쪽 개발 및 운영을 담당하는 입장으로써 API 지연 현상은 너무 자주 발생하는 현상이다..
작년 12월 말에 5대의 서버에서 수용할 수 있는 리소스를 넘는 트래픽이 들어온 경험이 있다. 그래서 ECS Container의 API의 Thread 갯수를 200개에서 → 262개로 조정을 한 경험이 존재한다..
01-6. 쓰레드 풀 - 요청마다 쓰레드 생성의 단점 보완
- 특징
- 필요한 쓰레드를 쓰레드 풀(Thread Pool)에 보관 및 관리
- 쓰레드 풀(Thread Pool)에 생성 가능한 쓰레드 최대치 관리 (톰캣은 최대 200개 기본 설정)
- 사용
- 쓰레드 필요 시 이미 생성된 쓰레드 풀(Thread Pool)에서 꺼내 사용
- 사용 종료 시 쓰레드 풀(Thread Pool)에 반환
- 최대 쓰레드가 모두 사용중 → 쓰레드 풀에 쓰레드 없음?
- 연결을 끊어버리거나 대기하도록 설정 가능
- 장점
- 쓰레드가 미리 생성되어있어 리소스(CPU, Memory) 절약, 응답 시간 빠름
- 쓰레드 최대치가 있어 과한 트래픽이 들어와도 기존 요청 안전하게 처리 가능
01-7. 쓰레드 풀 - 실무 팁
- WAS의 주요 튜닝 포인트 → 최대 쓰레드(max thread) 수이다
- 필자는 undertow WAS를 사용중인데, yml 파일에 max-thread 설정을 한 경험이 있음
server: port: 10091 undertow: io-threads: 16 worker-threads: 200
- 최대 쓰레드 수가 너무 낮으면?
- 서버 리소스는 여유롭지만, 클라이언트는 응답 지연
- 최대 쓰레드 수가 너무 높으면?
- 트래픽 많으면 서버 리소스(CPU, Memory) 임계점 초과로 서버 터짐
- 장애 발생 시?
- 클라우드 → 서버 증설 → 이후 성능 튜닝
- 클라우드 x → 열심히 성능 튜닝
01-8. 쓰레드 풀 - 쓰레드 풀의 적정 숫자를 어떻게 산정?
- 애플리케이션 로직 복잡도, CPU, Memory, IO 리소스 상황에 따라 다름
- 성능 테스트
- 최대한 실제 서비스와 유사하게 성능 테스트 시도
- 툴: 아파치 ab, jmeter, nGrinder
01-9. 핵심) WAS의 멀티 쓰레드 지원
- 멀티 쓰레드에 대한 부분은 WAS가 처리
- 개발자는 멀티 쓰레드 관련 코드 신경쓰지 않아도 됨
- 개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 코드 개발
- 멀티 쓰레드 환경이므로 싱글톤 객체(서블릿, 스프링 빈)은 주의해서 사용 필요
'Spring MVC > Spring MVC - 백엔드 웹 개발 기술 2탄' 카테고리의 다른 글
[스프링 MVC - 백엔드 웹 개발 기술] HttpServletRequest 개요와 기본 사용법 (0) | 2023.05.07 |
---|---|
[스프링 MVC - 백엔드 웹 개발 기술] 서블릿 생성 해보기 (0) | 2023.05.07 |
[스프링 MVC - 백엔드 웹 개발 기술] Spring Boot MVC 프로젝트 생성 (0) | 2023.05.07 |
[스프링 MVC - 백엔드 웹 개발 기술] HTML, HTTP API, CSR, SSR, 자바 백엔드 기술 웹 역사 (0) | 2023.04.30 |
[스프링 MVC - 백엔드 웹 개발 기술] 웹서버(Web Server), 웹 애플리케이션 서버(WAS) 그리고 서블릿 (0) | 2023.04.25 |