멀티 스레드

jihan kong·2022년 7월 4일
0

Spring MVC

목록 보기
3/12
post-thumbnail

본 시리즈는 인프런 학습 사이트의 김영한 강사님의 java spring mvc - 백엔드 웹 개발 핵심 기술 편을 학습한 내용을 바탕으로 정리하였습니다.


지난 포스팅에서 서블릿과 서블릿 컨테이너에 대해서 학습했다. 톰캣과 같이 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 하며 서블릿 컨테이너는 여러가지 특징들이 존재했다. 서블릿 객체를 생명주기로 관리하며 싱글톤으로 관리된다. 또한, 서블릿 컨테이너는 동시요청을 위한 멅티 스레드 처리를 지원한다고 했는데, 그렇다면 멀티 스레드가 과연 무엇일까?

동시요청 - 멀티 스레드

클라이언트에서 요청(request)을 보내면 WAS에서는 응답(response)을 해준다는 것은 이제 우리가 알고 있다. 위와 같이 요청이 들어오게 되면 WAS의 TCP/IP 통신을 통해 커넥션이 연결되어진다. 이후, WAS는 서블릿을 호출한다.

그렇다면 이때, Servlet을 호출해주는 존재는 무엇일까?

스레드 (thread)

Servlet, jsp와 같이 동적으로 이루어진 애플리케이션 코드를 하나하나 순차적으로 실행하는 것은 스레드가 하는 일이다. 자바 공부를 해본 사람이면 알겠지만 자바는 처음에 메인 메소드(main) 를 실행시키는데 이 때도 스레드가 동작하여 실행시키는 것이다.

이처럼 스레드가 없다면 자바 애플리케이션을 실행하는 것 자체가 불가능한데 아쉽게도 스레드는 한번에 하나의 코드 라인만 수행이 가능하다. 따라서 동시 처리가 필요하면 스레드를 추가로 생성해야만 한다.

단일 요청 - 스레드 하나만 사용

단일 요청의 경우, 위의 네 단계를 거친다. 휴식 중의 스레드는 request가 들어오게 되면 WAS를 통해 자동으로 스레드를 할당시키고 스레드는 servlet을 호출한다. servlet은 들어온 request에 대한 response를 수행하고 스레드는 휴식 단계에 접어들게 된다.

그렇다면 다중 요청이 들어올 때, 스레드 하나만 사용하고 있다면 어떻게 될까?


다중 요청 - 스레드 하나만 사용

다중 요청을 보냈을 때, 스레드를 하나만 사용하게 되면 위와 같은 문제가 발생한다. 요청1의 응답을 보내느라 동시에 들어온 요청2의 응답을 즉각적으로 처리해줄 수가 없다. 즉, 처리 지연이 발생한다. 이를 해결하기 위해선 스레드를 각 요청마다 생성해주는 방법을 사용해야한다.

다중 요청 - 요청마다 스레드 생성


다중 요청시, 요청이 올때마다 스레드를 생성하면 다음과 같은 장단점이 존재한다.

  • 장점
    • 동시 요청을 처리할 수 있다.
    • 리소스(CPU, 메모리)가 허용할 때 까지 처리가능.
    • 하나의 쓰레드가 지연 되어도, 나머지 쓰레드는 정상 동작한다.

  • 단점
    • 쓰레드는 생성 비용은 매우 비싸다.
      • 고객의 요청이 올 때 마다 쓰레드를 생성하면 응답 속도가 늦어진다.
    • 쓰레드는 컨텍스트 스위칭 비용이 발생한다.
    • 쓰레드 생성에 제한이 없다.
      • 고객 요청이 너무 많이 오면 CPU, 메모리 임계점을 넘어서 서버가 죽을 수 있다.

단점의 내용을 살펴보면 스레드 생성에 제한이 없다는 것이 특징이다.

제한이 없다면 보통 좋은데 왜 단점일까? 고객의 요청이 너무 많이올 때를 가정해보자. 예를 들어, 고객 주문이 10000개가 들어온다면 생성에 제한이 없기 때문에 주문의 양대로 스레드가 폭발적으로 생성된다. CPU가 버틸 수 있을 리가 없다. 이렇게 되면 서버가 죽어버릴 것이다. 이러한 단점을 보완하기 위해 WAS는 다음과 같은 구조를 가지고 있다.

스레드 풀 (thread pool)

"스레드 풀" 이란 말 그대로 필요한 스레드를 풀에 보관하고 관리한다는 이야기이다. 스레드 풀에 생성 가능한 스레드의 최대치를 관리한다. (톰캣은 최대 200개가 기본 설정이며 변경이 가능하다.)

동작 방식

스레드가 필요하면 이미 생성되어 있는 스레드를 스레드 풀에서 꺼내서 사용하고, 사용이 종료되면 스레드 풀에 해당 스레드를 반납한다. 만약 최대 스레드가 모두 사용중이어서 스레드 풀에 스레드가 없다면 요청을 거절하거나 특정 숫자만큼만 대기하도록 설정할 수 있다.

장점

스레드가 미리 생성되어 있으므로 스레드를 생성하고 종료하는 비용이 절약되고, 응답시간이 빠르다. 또한, 생성 가능한 스레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청을 안전하게 처리할 수 있다.

profile
학습하며 도전하는 것을 즐기는 개발자

0개의 댓글