Spring MVC : 동시요청 멀티 쓰레드 간단한 개념
- Spring/Spring MVC
- 2021. 12. 8.
클라이언트의 요청
- 클라이언트가 서버로 요청을 하면 WAS는 응답을 한다.
- TCP/IP 커넥션이 연결되고 서블릿이 호출된다.
→ 이 때 서블릿은 '쓰레드'가 호출해준다.
쓰레드
- 쓰레드는 서블릿을 호출해주는 역할을 한다.
- 쓰레드는 어플리케이션 코드를 순차적으로 실행해준다.
- 자바 메인 메서드를 처음 실행하면 main이라는 이름의 쓰레드가 실행된다.
- 쓰레드가 없다면 자바 어플리케이션은 실행이 불가능하다. 왜냐하면 실행시켜주는 애가 없기 때문이다.
- 쓰레드는 한번에 하나의 코드 라인만 실행한다. 따라서 동시 처리가 필요하면 여러 쓰레드가 필요하다.
단일 요청 - 쓰레드 하나만 있을 때
- 클라이언트에서 서버로 요청이 온다.
- WAS는 이 요청에 놀고 있는 쓰레드를 할당해준다.
- 쓰레드는 이 요청에 대한 서블릿을 호출한다.
- 쓰레드는 응답을 반환해주고, 다시 휴식한다.
다중 요청 - 쓰레드 하나만 있을 때
- '요청1'이 요청되어 휴식하고 있던 쓰레드는 요청1에 할당됨.
- '요청1'의 쓰레드가 불의의 사건으로 서블릿에서 처리가 지연되고 있다고 가정해본다.
- 이 때 '요청2'가 들어오면, '요청2'는 사용 가능한 쓰레드가 없기 때문에 쓰레드를 위해 대기한다.
위와 같은 상황이 발생하면 쓰레드 하나만 있을 때는 어떠한 요청도 제대로 처리할 수 없다는 것을 알게 된다. 1번은 비즈니스 로직이 느리다는 이유로 처리가 지연되고 있을 수 있고, 2번 요청은 1번 요청이 처리될 때까지 쓸 수 있는 쓰레드가 없기 때문에 계속 기다려야한다. 하나도 제대로 실행이 안된다.
요청마다 쓰레드 생성
요청마다 쓰레드 생성은 말 그대로 '요청이 올 때 마다 새로운 쓰레드를 생성해서 배정해준다'이다. 이것들의 장단점을 알아보면 아래와 같다.
- 장점
- 동시 요청을 처리할 수 있음.
- 하나의 쓰레드가 지연되어도, 다른 쓰레드는 정상 동작한다.
- 단점
- 쓰레드는 생성 비용이 매우 비싸다. (매번 생성하면 응답속도가 느려질 수 있음)
- 쓰레드는 컨텍스트 스위칭 비용이 발생함. (코어 개수만큼 CPU 있고, CPU 개수만큼 동시 쓰레드 처리 가능함. 코어가 1개만 있다면 1개의 쓰레드를 실행 후, 그 다음 쓰레드로 넘어가게 되는데 이 때 컨텍스트 스위칭 비용이 발생한다.)
- 쓰레드 생성에 제한이 없다. (고객 요청이 한번에 많이 오면, CPU, 메모리 등의 임계점이 넘어서 뻗을 수 있음)
쓰레드 풀(요청마다 쓰레드 생성의 단점 극복)
WAS는 주로 '쓰레드풀'을 사용해서 동시 처리를 도와준다. WAS에는 초기에 설정된 값만큼 쓰레드가 미리 만들어진다. 그리고 요청이 올 때 마다 쓰레드 풀에서 쓰레드를 가져다쓰고, 쓰레드 사용이 완료되면 쓰레드를 반납한다(삭제하지 않음)
- 특징
- 필요한 쓰레드를 쓰레드 풀에 보관하고 관리한다.
- 쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리함. (톰캣은 200개)
- 사용
- 쓰레드가 필요하면, 쓰레드 풀에서 가져다 쓴다.
- 쓰레드 풀에 사용가능한 쓰레드가 없다면?
→ 기다리는 요청을 거절하거나, 특정 숫자만큼 대기하도록 설정한다.
- 장점
- 쓰레드가 미리 생성되어 있기 때문에 쓰레드를 생성 및 종료하는 비용이 절약되고, 응답시간이 빠르다.
- 생성 가능한 쓰레드의 최대치를 고려해서 초기에 설정되기 때문에 요청을 안전하게 처리할 수 있다.
WAS 실무팁
WAS의 주요 튜닝 포인트는 최대 쓰레드를 어떻게 설정할 것인지를 정하는 것이다
만약 쓰레드가 너무 적다면?
동시 요청이 많으면 서버 리소스는 여유롭지만, 클라이언트는 응답이 지연된다. 따라서 CPU는 5%만 사용하고 있는데, 응답 지연이 발생하고 있으니 서버가 너무 모자라구나 라는 생각을 하고 서버를 늘릴 수 있다. 최대 쓰레드 개수가 적게 설정되면 이런 불상사가 발생할 수 있다고 한다.
만약 쓰레드가 너무 많다면?
오히려 반대로 이 경우에는 서버가 죽을 수 있다. 동시 요청이 많을 것을 가정하고 임계점 근처에 놓고 쓰게 된다면, 실제로 그렇게 많은 동시 요청이 오면 동시에 처리하다가 서버가 죽는 경우가 발생한다.
위의 경우를 살펴보면 적정선을 유지하는 것이 중요한 것을 볼 수 있다. 만약 서버에서 응답지연이 발생한다면, 먼저 서버를 늘려서 안전하게 잘 동작하도록 유지를 한다. 그리고 쓰레드 개수 튜닝을 해서 최적화를 하는 방법으로 접근해야한다고 한다.
쓰레드 풀의 적정 갯수를 찾는 방법은 딱히 정해져 있지 않다. 왜냐하면 어플리케이션의 비즈니스 로직이 얼마나 복잡한지, I/O이 리소스가 어떤지에 따라서 상황이 모두 다르기 때문이다. 보통은 최대한 실제 서비스와 유사하게 성능 테스트를 해서 결정한다고 한다. 이 때 사용 가능한 툴은 아파치 ab, 제이미터, nGrinder 같은 것들이라고 한다.
요약
- WAS는 멀티 쓰레드를 지원해준다.
- 멀티 쓰레드에 대한 처리는 WAS가 한다 → 개발자는 멀티 쓰레드 관련 코드 신경 쓰지 않아도 됨.
- 개발자는 싱글 쓰레드 프로그래밍처럼 코드를 작성하면 됨.
- 멀티 쓰레드 환경이기 때문에 싱글톤 객체(서블릿, 스프링 빈)은 주의해서 사용해야한다.
'Spring > Spring MVC' 카테고리의 다른 글
Spring MVC : 스프링 환경에서 서블릿 사용해보기 (0) | 2021.12.09 |
---|---|
Spring MVC : 스프링 스타터로 프로젝트 생성하기 (0) | 2021.12.09 |
Spring MVC : HTML, HTTP API, CSR, SSR (0) | 2021.12.09 |
Spring MVC : 서블릿 간략 정리 (0) | 2021.12.09 |
스프링 MVC, 웹 어플리케이션 이해하기 (0) | 2021.12.06 |