-
서블릿(Servlet)과 멀티 쓰레드(Multi Thread)의 간략한 개념과 정의Web Programming 2022. 3. 11. 16:58
안녕하세요 이번 포스팅은 Servlet에 대해서 간략하게 알아보겠습니다.
위의 사진과 같이 간단한 HTML FORM이 있다고 가정합시다. input 태그에 내용을 입력하고 전송 버튼을 눌러서 submit 하게 되면 오른쪽의 사진과 같이 요청 HTTP 메시지가 생성됩니다.
HTTP 메시지의 first line을 포함해서 http header 그리고 http body가 같이 전송이 되어지는데요, http headers는 데이터에 대한 부가정보, 그리고 http body에는 전송할 데이터가 담겨있습니다.
아무튼, 이런 데이터를 Tomcat과 같은 WAS(Web Application Server)에 전송하게 되면, WAS는 다음과 같은 로직을 수행해야 합니다.
HTTP message를 읽어 들여야 하기 때문에, 서버는 TCP 연결을 위해 항상 대기하고 있다가 요청이 오면 연결을 하고 HTTP 메시지를 파싱 해서 아주 많은 정보를 읽어 들여야 합니다.
개발자가 이런 모든 작업을 프로그래밍하려면 비효율적이고 힘들겠죠? 그래서 이렇게 귀찮고, 어렵고 반복적인 일을 서블릿을 지원하는 WAS에 위임합니다.
그렇다면 위의 사진과 같이 개발자는 오직 비즈니스 로직 실행에만 집중하게 되고 나머지는 전부 WAS가 대신 처리를 해줍니다.
서블릿의 특징
위의 사진들을 보면 몇 가지 특징을 찾을 수 있습니다.
1. urlPatterns(/hello)의 URL이 호출되면 서블릿 코드가 실행됩니다.
2. HTTP 요청 정보를 편리하게 사용할 수 있는 HttpServletRequest를 지원합니다.
3. HTTP 응답 정보를 편리하게 제공할 수 있는 HttpServletResponse를 지원합니다.
그래서 개발자는 HTTP 스펙을 아주 편리하게 사용할 수 있는 것이죠
또한 위의 흐름을 정리해보자면
1. WAS는 Request, Resopnse 객체를 새로 만들어서 서블릿 객체를 호출합니다.
2. 개발자는 Request 객체에서 HTTP 요청 정보를 편리하게 꺼내서 사용합니다.
3. 개발자는 Response 객체에서 HTTP 응답 정보를 편리하게 입력합니다.
4. WAS는 Response 객체에 담겨있는 내용으로 HTTP 응답 정보를 생성합니다.
서블릿 컨테이너(Servlet Container)
1. 톰캣처럼 서블릿을 지원하는 WAS를 바로 서블릿 컨테이너라고 합니다.
2. 서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기를 관리합니다.
3. 서블릿 객체는 싱글톤으로 관리됩니다.
- 고객의 요청이 올 때마다 계속 객체를 생성하는 것을 비효율적입니다.
- 최초 로딩 시점에 서블릿 객체를 미리미리 만들어주고 재활용합니다.
- 모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근합니다.
- 그래서 공유 변수 사용에 주의해야 합니다!!!!
- 서블릿 컨테이너 종료 시 함께 종료됩니다.
4. JSP도 서블릿으로 변환되어서 사용됩니다.
5. 동시 요청을 위한 멀티 스레드 처리를 지원합니다.
동시 요청 멀티 스레드(Multi Thread)
브라우저가 WAS에게 Request 요청을 보내면 WAS는 요청에 맞게 서블릿 객체를 생성해서 비즈니스 로직을 수행해야 하는데 이것을 누가 담당할까요?
바로 그것을 스레드가 해줍니다.
자바에서 자주 사용하는 메인 메서드도 실행하면 main이라는 이름의 스레드가 실행되는 것입니다.
쓰레드가 없다면 자바 애플리케이션 실행이 불가능하고, 스레드는 한 번에 하나의 코드 라인만 수행이 됩니다.
또한, 동시 처리가 필요하다면 스레드를 추가 생성하면 됩니다.
위의 그림과 같이 단일 요청이면 스레드를 하나면 사용하면 되기 때문에 큰 문제가 되지 않습니다.
하지만 다중 요청이 들어오면 어떨까요?
스레드는 하나인데 다중 요청에 들어오게 되면 다른 Request 요청은 스레드의 사용이 끝날 때까지 대기해야 합니다.
또한 여기서 만약 기존의 스레드가 로직을 수행하다가 장애 발생 시 결국 2개의 요청 전부 다 처리할 수 없는 문제가 생깁니다.
그렇기 때문에 요청이 올 때마다 스레드를 생성하는 것이 하나의 방법입니다.
위의 사진과 같이 쓰레드를 여러 개 사용하게 되면 하나의 Request에서 장애가 발생하더라도 다른 Request는 영향을 받지 않습니다.
하지만 요청마다 스레드를 생성하는 것은 장단점이 있습니다.
장점
1. 동시 요청을 처리할 수 있다
2. 리소스(CPU, 메모리)가 허용할 때까지 처리 가능
3. 하나의 스레드가 지연되어도, 나머지 스레드는 정상 동작한다.
단점
1. 스레드의 생성 비용은 매우 비싸다.
- 고객의 요청이 올 때마다 스레드를 생성하면, 응답 속도가 늦어진다.
2. 스레드는 콘텍스트 스위칭 비용이 발생한다.
- 스레드는 동시에 실행되는 것처럼 보이지만 그것이아니라, 너무 빠르게 실행 되기 때문에 동시에 수행되는 것처럼 보이는 것입니다. 여러개의 쓰레드를 왔다갔다 하면서(스위칭) 실행 할 때 많은 비용이 발생합니다.
3. 쓰레드는 생성에 제한이 없다.
- 고객 요청이 너무 많이 오면, CPU, 메모리 임계점을 넘어서 서버가 죽을 수도 있다.
그렇다면 위의 단점을 어떻게 해결할 수 있을까요?
스레드 풀(Thread Pool)
스레드 풀을 사용해서 요청 마다 쓰레드를 생성 할 때의 단점을 극복 할 수 있습니다.
특징
1. 필요한 쓰레드를 쓰레드 풀에 보관하고 관리한다.
2. 쓰레드 풀에 생성 가능한 스레드의 최대치를 관리한다. 톰캣은 최대 200개 기본 설정(변경 가능)
사용
1. 스레드가 필요하면, 이미 생성되어 있는 쓰레드를 쓰레드 풀에서 꺼내서 사용한다.
2. 사용을 종료하면 쓰레드 풀에 해당 쓰레드를 반납한다.
3. 최대 스레드가 모두 사용중이어서 쓰레드 풀에 쓰레드가 없으면?
- 기다리는 요청은 거절하거나 특정 숫자만큼만 대기하도록 설정할 수 있다.
장점
1. 쓰레드가 미리 생성되어 있으므로, 스레드를 생성하고 종료하는 비용(CPU)이 절약되고, 응답 시간이 빠르다.
2. 생성 가능한 스레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있다.
실무 팁
실무에서 적용해보자면, WAS의 주요 튜닝 포인트는 최대 스레드(max thread) 수라고 합니다.
이 값을 너무 낮게 설정하면 동시 요청이 많아질 때 서버 리소스는 여유롭지만, 클라이언트는 응답이 지연됩니다.
또한 이 값을 너무 높게 설정하면 동시 요청이 많아 질 때 CPU, 메모리 리소스 임계점 초과로 서버가 다운될 수도 있습니다.
서버 리소스를 효율적으로 사용하기 위해 스레드의 최대 수를 10개로 제한 하고 CPU의 5%만 사용했다고 가정 해봅시다. 그렇다면 CPU의 너무 많은 자원이 놀고있기 때문에 리소스를 적절히 활용했다고 할 수없겠죠. 그래도 CPU의 50%정도는 사용 해주어야한다고 합니다.
쓰레드 풀의 적정 숫자는 애플리케이션 로직의 복잡도, CPU, 메모리, IO 리소스 상황에 따라 모드 다르기 때문에 많은 테스트를 해봐야 된다고 합니다.
핵심
1. 멀티 스레드에 대한 부분은 WAS가 처리합니다.
2. 개발자가 멀티 스레드 관련 코드를 신경쓰지 않아도 됩니다,
3. 개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 코드를 개발하면 됩니다.
4. 멀티 쓰레드 환경이므로 싱글톤 객체는 주의해서 사용해야 합니다.
'Web Programming' 카테고리의 다른 글
HTML, HTTP API, CSR, SSR의 간략한 개념과 정의 (0) 2022.03.11 URI, URL, URN의 개념과 차이점 (0) 2022.02.16 DNS(Domain Name System)의 개념과 정리 (0) 2022.02.15 Web Server와 WAS(Web Application Server)의 차이점 파악하기 (0) 2022.02.12