인프런 강의

WAS의 Servlet (feat. Multi Thread)

WolrdOtaku 2023. 6. 29. 19:11

HTML Form

보통 HTML에서 Form에 데이터를 넣고 submit을 할 때 아래와 같이 구현하고는 한다.

코드

왼쪽 - Form 코드 / 오른쪽 - 웹 브라우저에서 생성한 요청 HTTP메시지

서버에서 클라이언트로부터 저 HTTP 요청 메시지를 받으면 어떻게 처리하지??

 


Servlet

Servlet에 대해 알아보기 전에 HTTP (요청) 메시지(오른쪽) 에 대해서 생각해보자.

만약에, Servlet이 없다면??

HTTP (요청/응답) 메시지를 작성하기 위해서 왼쪽에 있는 모든 내용을 서버에서 수작업으로 작성해줘야 한다.

즉, Servlet은 핵심 로직인 비즈니스 로직 실행 부분(초록색 네모박스)을 제외한 모든 부분의 자동화 기능을 제공한다.

 


Servlet 동작 원리

: tomcat WAS에서는 Servlet을 지원한다. ⇒ Servlet 컨테이너가 존재

  1. 웹 브라우저에서 localhost:8080/hello 를 엔터.
  2. 이 때! WAS 서버에서는 “/’ 에 대한 HTTP 요청 메시지의 새로운 request, response 객체를 새로 만든다.
  3. 만들어진 객체를 Servlet 컨테이너의 helloServlet에서 실행해준다.
  4. 개발자가 request, response 객체를 편하게 가공한다.
  5. WAS가 가공된 response 객체의 내용을 HTTP 응답정보로 사용자에게 보낸다.

Servlet이 2~4 과정을 Form 데이터로 야기한 HTTP 요청 메시지에 대해 편리하게 사용할 수 있도록 자동화 과정을 책임진다.

Servlet 컨테이너

: 톰캣처럼 서블릿을 지원하는 WAS를 뜻한다.

: Servlet 객체의 생명주기(생성, 호출, 종료)를 관리하는 역할

 

Servlet 생명주기

: 사용자 요청이 올 때마다 끝없이 객체를 생성하는 것은 비효율적이기 때문에 Servlet은 아래와 같이 싱글톤으로 관리된다.

  • 최초 로딩시점에 서블릿 객체를 미리 만들어두고 재활용.
  • ⇒ 따라서, 모든 요청 은 동일한 Servlet 객체 인스턴스에 접근하는 것.
  • 멤버 변수(공유 변수) 사용할 때는 주의해야 한다.
    • 예를 들어, 남이 로그인했는데 내 로그인 정보가 보이면 안되기 때문이다.
  • 참고) JSP도 결국 “JSP → Servlet” 과 같이 변환돼서 사용되는 것이다.

Servlet을 지원한 WAS의 진짜 목적은 동시요청을 위한 멀티 쓰레드 처리를 지원해주는 것임을 명심해야 한다.

예를 들어, 사용자가 100명, 10000명이 동시에 서버에 api 요청을 한다. 그럼에도 잘 처리할 수 있는 이유는 멀티쓰레드를 지원하기 때문이다.

 


동시 요청 - Multi Thread

  • 쓰레드는 Servlet을 실행시킨다.
    • 예를 들어, 자바 main 메서드를 처음 실행시키면 main이라는이름의 쓰레드가 실행된다.
  • 동시처리가 더 필요하면 쓰레드를 추가로 생성한다.
  • 참고) 쓰레드가 없으면 자바 애플리케이션이 실행 자체가 불가능하다.
  • 참고) 쓰레드는 한번에 하나의 코드라인만 수행한다.

동시 처리를 위한 쓰레드 추가 생성

  1. 클라이언트로부터 요청1이 왔다.
  2. WAS 내의 쓰레드가 servlet를 실행시킨다.
  3. 그런데, 만약 “servlet내에서 처리지연이 발생했다!” 고 가정해보자.
  4. 이런 과정중에 또 다른 클라이언트에서 요청2를 보내게 된다.
  5. 그러면, 쓰레드 하나는 요청1을 처리중이라 요청2에 대해서 처리를 못한다
  6. ⇒ 요청2는 기다려야 해서 “쓰레드 대기”가 발생

결국 문제점은 이러다 두 요청 다 죽을 수 있다는 것이다!!

 

++ 2023.09.03 추가

쉽게 말해서, 이마트(WAS) 가면 손님-계산해주는사람-계산대가 쓰레드는 계산해주는 사람이라고 생각하시면 위 상황을 이해하기 쉬울 것입니다.

 

다시 말해서,
이마트에서 처리해야 할 사람이 많으면, 이마트 자체 더 생성 := 프로세스 더 생성
한 이마트 내에서 처리할 수 있다면, 계산해주는 사람 더 생성 := 쓰레드 더 생성

 


단일 쓰레드 해결 방법

⇒ 단순히 요청 마다 쓰레드 생성하는 방법을 떠올릴 수 있다.

그런데!!! 이 방법도 장단점이 있다.

장점

  • “동시 요청” 처리 가능
  • CPU, 메모리가 허용하는 선에서 모든 요청 처리 가능
  • 하나의 쓰레드가 지연되도, 다른 쓰레드가 동작

단점

  • 쓰레드 생성비용이 엄청엄청엄청엄청 비싸다.
    • 고객 요청올때 마다 새로운 쓰레드생성하면, ‘쓰레드 생성 시간’ 발생
    • ⇒ 응답속도가 느려지게 됨.
  • 쓰레드의 ‘컨텍스트 스위칭’ 비용 발생
  • 고객 요청온다고 해서, 쓰레드 생성에 제한없이 막 생성시키면 CPU, 메모리 임계점을 넘어서 서버 자체가 뻗을 수 있다.
    • 예를 들어) 수강신청할때, 학생들 요청이 갑자기 너무많으면 WAS내에서 그 일 처리할려고 쓰레드가 계속 생성된다. (얼른얼른!!) 그러다가 CPU, 메모리 임계점 넘어서 서버가 다운되는 것이다;;
    • A: “아 짜증나!! 우리학교 서버는 왜 이렇게 다운 되는거야????”
    • 나: 아~ 쓰레드 풀의 모든 쓰레드가 다른 요청을 처리하고 있어서 우리 컴퓨터의 요청에 대한 쓰레드는 현재 쓰레드 풀에 없는가봐~~
    • 하고 대답할 수 있겠다 ㅎㅎㅎ

참고) 컨텍스트 스위칭 비용

  • 컴퓨터의 CPU의 코어가 하나라고 가정한다.
  • 코어는 하나인데, 쓰레드가 2개라면 어떻게 동작할까??
  • ⇒ 쓰레드는 동시에 작동하는 것처럼 보.여.도! 사실은 CPU코어가 빨리빨리 번갈아가면서 쓰고 있다. 이 때 발생하는 비용을 컨텍스트 스.위.칭이라고 한다.

요청 마다 쓰레드 생성 해결법

⇒ 쓰레드 풀 생성

: 풀(Pool)이 말 그대로 어린애들 풀장 같은 것

  • 풀장에서 쓰레드들 한 300개가 놀고 있다가, 사용자 요청에 따라 이 풀장에서 꺼내서 일 시키는것이다 😂
  • 그렇게 일하고 온 쓰레드들은 다시 쓰레드 풀로 돌아가서 신나게 노는거다 😎
  • 그런데! 만약에 엄청 바빠서 쓰레드 풀에 쓰레드가 한명도 없다! 그러면?? 이 후 처리들은 ‘쓰레드 대기 or 거절’ 모드로 처리되는 것. 5명까지는 대기 받을게요:)
  • 참고) 사용자 요청은 작업 큐(Queue)를 통해서 들어온다. := 동시성 보장

쓰레드 풀

: CPU가 사용자요청을 처리하기 위해 “쓰레드들을 미리 생성 → 일정공간에 보관” 해두는 방법

  • ‘고객 요청마다 쓰레드 생성’ 방식의 단점을 보완하는 솔루션

쓰레드 풀 특징

  • WAS 내 필요한 쓰레드들은 쓰레드 풀에 보관되고, WAS에 의해 관리됨.
  • WAS는 ‘쓰레드 풀’에 보관 가능한 ‘쓰레드 최대치’를 관리한다.
    • 참고) 톰캣은 최대 200개 default

쓰레드 풀 사용

  1. 사용자 요청이 들어오면, 쓰레드 풀에 이미 생성되어있는 쓰레드를 꺼내서 사용
  2. 사용을 종료되면, 쓰레드 풀에 해당쓰레드를 반납

만약에, 최대 쓰레드가 모두 사용중이여서 쓰레드 풀에 쓰레드가 없으면?

⇒ 기다리는 요청은 거절하거나 특정숫자만큼 대기하도록 설정가능해요

 

쓰레드 풀 장점

  • 쓰레드가 미리 생성되어 있다.⇒ 응답 시간이 빠름
  • ⇒ 쓰레드를 생성 & 종료하는 비용(CPU)이 절약
  • 생성가능한 쓰레드의 최대치를 정해놓음
  • ⇒ 많은 요청이 들어올 때, 기존의 처리 중인 작업은 안전하게 처리 가능