Programming/Spring

[MVC] 동시요청 - 멀티쓰레드 (Multi-Thread)

Supreme_YS 2022. 6. 7. 21:46

* 배경 상황 : Http 요청 -> TCP/IP 연결 (Connection) -> 서블릿 객체 호출 

이 때, 서블릿 객체를 호출하는 것은 무엇인가? 쓰레드다.

 

* 쓰레드의 특징

- 애플리케이션 코드를 하나하나 순차적으로 실행하는 것이 쓰레드

- 예. 자바 main 메서드를 처음 실행하면 main 이라는 이름의 쓰레드가 실행

- 쓰레드는 한 번에 하나의 코드 라인만 실행

- 동시 처리가 필요하면 쓰레드를 추가로 생성

 

* 단일요청이라면?

- 단일 요청이 왔다면 연결 시에 쓰레드를 하나 할당한 후, 서블릿을 호출해서 응답을 해주면 된다.

 

* 근데 문제는 다중요청이라면?

- 다중 요청(한 개 이상의 요청)시 한 개의 쓰레드를 점유하고 있기 때문에 다른 요청을 처리되지 못하고 대기하고 있게 되어 서비스 지연의 문제점이 발생할 수 있다.

- 그러면 쓰레드를 늘리면 되는 거 아니냐? --> 직관적으로 생각하면 맞는 말이긴 하지만 여러 문제들이 발생할 수 있다.

 

* 쓰레드를 여러개로 늘리면 발생하는 문제들

- 쓰레드를 생성하는 데 비용(시간)이 많이 발생한다. 요청마다 쓰레드를 생성하면 응답 속도가 늦어질 수 밖에 없다.

- 쓰레드는 컨텍스트 스위칭 비용이 발생한다. (컨텍스트 스위칭 : 코어에서 쓰레드를 전환하는 것)

- 쓰레드 생성에 제한이 없기 때문에 요청이 많이 온다면 메모리가 버티지 못하고 죽을 수 있다.

 

* 그러면 어떻게 하냐

- 쓰레드를 죽이고(없애고), 생성하는 개념이 아니라

- 쓰레드 풀(Pool)을 둠으로써, 쓰레드들을 미리 생성해놓고 쓰레드 풀에서 요청시에 놀고 있는 쓰레드를 쓰고 반납하는 방식을 사용한다.

- 쓰레드 풀의 쓰레드도 다 사용중이면 대기, 거절을 통해 처리한다.

 

* 쓰레드 풀 실무 팁

- WAS의 주요 튜닝 포인트는 MAX Thread(최대 쓰레드 수) 이다.

- 이 값을 너무 낮게 설정하면 동시 요청 시, 서버 리소스는 여유롭지만 클라이언트는 응답 지연

- 이 값을 너무 높게 설정하면 동시 요청 시, CPU나 메모리 리소스 임계점 초과로 서버 다운

- 따라서, 장애 발생 시 클라우드 환경이라면 서버부터 증설하고 이후 튜닝 

- 클라우드가 아니면 열심히 튜닝..

 

* 쓰레드 풀 적정 숫자 어떻게 찾나

- 애플리케이션 로직의 복잡도, CPU, 메모리, IO 리소스 상황에 따라 다르다

- 따라서, 성능 테스트를 해봐야한다. 최대한 실제 서비스와 유사한 환경으로 테스트를 해본다.

- Apache ab, Jmeter, nGrinder와 같은 툴로 테스트를 진행한다.

 

* 근데 멀티 쓰레드는 WAS가 관리해줌 ^^

* 따라서, 멀티 쓰레드 관련해서 신경쓰지 않아도 되고, 싱글 쓰레드로 동작하는 것처럼 편하게 개발하면 된다.

* 단, 싱글톤 객체(서블릿, 스프링 빈)는 주의해서 사용 (멤버변수가 공유변수가 되기 때문에 조심해야 함)