서블릿, 쓰레드

LeeKyoungChang·2022년 9월 15일
1
post-thumbnail

'스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술' 수업을 듣고 정리한 내용입니다.

 

📚 1. 서블릿이란 무엇인가?

✔️ 서버에서 처리해야하는 업무

(1) 만약, 웹 애플리케이션 서버 직접 구현이라면?

- 서버 TCP/IP 연결 대기, 소켓 연결
- HTTP 요청 메시지를 파싱해서 읽기
- POST 방식, /save URL 인지
- Content-Type 확인
- HTTP 메시지 바디 내용 피싱
	- username, age 데이터를 사용할 수 있게 파싱
- 저장 프로세스 실행
- 비즈니스 로직 실행
	- 데이터베이스에 저장 요청
- HTTP 응답 메시지 생성 시작
	- HTTP 시작 라인 생성
	- Header 생성
	- 메시지 바디에 HTML 생성에서 입력
- TCP/IP에 응답 전달, 소켓 종료
  • 여기서 의미있는 비즈니스 로직 : 비즈니스 로직 실행(데이터베이스에 저장 요청)
  • 하지만, 실행하기 위해 되게 복잡하다.

 

(2) 만약, 서블릿을 지원하는 WAS 사용

WAS : Web Application Server

- x
- x
- x
- x
- x
	- x
- x
- 비즈니스 로직 실행
	- 데이터베이스에 저장 요청
- x
	- x
	- x
	- x
- x
  • 간단해졌다.

 

 

📖 A. 서블릿

@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response{
		// 애플리케이션 로직
	}
}
  • urlPatterns(/hello) 의 URL이 호출되면 서블릿 코드가 실행된다.
  • HttpServletRequest : HTTP 요청 정보를 편리하게 사용할 수 있다.
  • HttpServletResponse : HTTP 응답 정보를 편리하게 제공할 수 있다.
  • **개발자는 HTTP 스펙을 매우 편리하게 사용한다.

 

✔️ HTTP 요청시 동작 과정

스크린샷 2022-09-15 오후 2 34 30
  • WASRequest, Response 객체를 새로 만들어서 서블릿 객체 호출
  • 개발자는 Request 객체에서 HTTP 요청 정보를 편리하게 꺼내서 사용
  • 개발자는 Response 객체에 HTTP 응답 정보를 편리하게 입력
  • WASResponse 객체에 담겨있는 내용으로 HTTP 응답 정보를 생성

 

✔️ 서블릿 컨테이너란?

스크린샷 2022-09-15 오후 2 50 33
  • 서블릿 컨테이너가 자동으로 helloServletsaveServlet를 관리해준다.

 

  • 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 한다.
  • 서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기 관리
  • 서블릿 객체는 싱글톤으로 관리
    - 고객의 요청이 올 때 마다 계속 객체를 생성하는 것은 비효율적이다.
    - 최초 로딩 시점에 서블릿 객체를 미리 만들어두고 재활용한다.
    - 모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근한다.
    - 공유 변수 사용 주의
    - 서블릿 컨테이너 종료시 함께 종료
  • JSP도 서블릿으로 변환 되어서 사용
  • 동시 요청을 위한 멀티 쓰레드 처리 지원

 

 

📚 2. 동시 요청 - 멀티 쓰레드

스크린샷 2022-09-15 오후 3 09 25

-> 서블릿 객체를 누가 호출하는 걸까??

 

✔️ 쓰레드

  • 쓰레드는 애플리케이션 코드를 하나하나 순차적으로 실행한다.
  • 자바 메인 메서드를 처음 실행하면 main이라는 이름의 쓰레드가 실행한다.
  • 쓰레드가 없다면 자바 애플리케이션 실행이 불가능하다.
  • 쓰레드는 한번에 하나의 코드 라인만 수행한다.
  • 동시 처리가 필요하면 쓰레드를 추가로 생성한다.

 

✔️ 단일 요청 - 쓰레드 하나 사용

스크린샷 2022-09-15 오후 3 14 10
  • 요청이 왔을 때, 쓰레드를 할당한다.
  • 쓰레드를 가지고 서블릿 코드를 실행한다.

 

스크린샷 2022-09-15 오후 3 14 01 - 응답 처리가 이루어진다.

 

완료 후,

스크린샷 2022-09-15 오후 3 15 43
  • 쓰레드는 휴식을 취한다.

 

 

✔️ 다중 요청 - 쓰레드 하나 사용

스크린샷 2022-09-15 오후 3 17 49
  • 요청1 처리중, servlet에서 처리 지연이 발생했다.
  • 이때 요청2가 요청을 시도한다.

 

스크린샷 2022-09-15 오후 3 17 55

-> 이와 같을 경우, 요청1과 요청2 동시 요청으로 인해 둘다 죽게 된다.

 

📣 그러면 요청마다 신규 쓰레드를 생성하면 되지 않을까?

스크린샷 2022-09-15 오후 3 20 21
  • 장점
    • 동시 요청을 처리할 수 있다.
    • 리소스(CPU, 메모리)가 허용할 때 까지 처리가능
    • 하나의 쓰레드가 지연 되어도, 나머지 쓰레드는 정상 동작한다.
  • 단점
    • 쓰레드는 생성 비용은 매우 비싸다.
      • 고객의 요청이 올 때마다 쓰레드를 생성하면, 응답 속도가 늦어진다.
    • 쓰레드는 컨텍스트 스위칭 비용이 발생한다.
    • 쓰레드 생성에 제한이 없다.
      • 고객 요청이 너무 많이 오면, CPU, 메모리 임계점을 넘어서 서버가 죽을 수 있다.

 

✔️ 해결책! - Watson, 쓰레드 풀

스크린샷 2022-09-15 오후 3 26 03
  • 서블릿 작업이 완료될 때까지 쓰레드 풀에 저장한다.
  • 쓰레드 풀에 쓰레드 요청을 하고, 쓰레드에서는 요청된 개수만큼 서블릿에서 사용된다.
  • 요청1, 요청2를 쓰레드 풀에 저장 후 서블릿에서 사용된다. (200 -> 198)
  • 다 사용될 시, 쓰레드 풀에 반납한다.

 

스크린샷 2022-09-15 오후 3 30 42
  • 쓰레드 한계 개수를 200개로 설정했다면, 201, 202 요청들은 쓰레드 풀에 쓰레드가 없기 때문에 쓰레드가 대기하거나, 거절된다.

 

✔️ 쓰레드 풀

요청 마다 쓰레드 생성의 단점 보완

  • 특징
    • 필요한 쓰레드를 쓰레드 풀에 보관하고 관리한다.
    • 쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리한다. 톰캣은 최대 200개 기본 설정 (변경 가능)
  • 사용
    • 쓰레드가 필요하면, 이미 생성되어 있는 쓰레드를 쓰레드 풀에서 꺼내서 사용한다.
    • 사용을 종료하면 쓰레드 풀에 해당 쓰레드를 반납한다.
    • 최대 쓰레드가 모두 사용중이어서 쓰레드 풀에 쓰레드가 없으면?
      • 기다리는 요청은 거절하거나 특정 숫자만큼만 대기하도록 설정할 수 있다.
  • 장점
    • 쓰레드가 미리 생성되어 있으므로, 쓰레드를 생성하고 종료하는 비용(CPU)이 절약되고, 응답 시간이 빠르다.
    • 생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있다.

 

✔️ 쓰레드 풀 - 실무 팁

성능 튜닝에 관한 얘기

  • WAS의 주요 튜닝 포인트는 최대 쓰레드(max thread) 수 이다.
  • 이 값을 너무 낮게 설정하면?
    • 동시 요청이 많으면, 서버 리소스는 여유롭지만, 클라이언트는 금방 응답 지연
스크린샷 2022-09-15 오후 3 39 33

최대 쓰레드 10개 설정, 동시에 10개의 요청만 가능
이와 같을 때, 100개의 요청이 온다면, 90개의 쓰레드가 대기, 거절하게 된다.
이때, 갑작스레 서버에 문제가 발생한다면?
개발자는 cpu 사용량을 확인했을 때 5%만 사용중이다.

-> 요청이 많이 와서 외부에서 수많은 쓰레드가 대기, 거절하고 있지만, 내부에서 볼 때 최대 개수만큼의 쓰레드 만 돌고 있어 계속 밀리면서 장애가 일어난다. (Waston은 정상 동작, 고객들은 전체적으로 장애 환경을 맡보게 된다.)

-> 결국, 개발자 입장에서는 setting을 잘못한 것이다. (왜냐면, 현재와 같은 100개의 데이터가 들어올 때는 cpu 50%를 사용해야하는데, 5%만 사용하고 있다.)

 

  • 이 값을 너무 높게 설정하면?
    • 동시 요청이 많으면, CPU, 메모리 리소스 임계점 초과로 서버 다운 (서버 다운될 시 복구하기 쉽지 않다.)
  • 장애 발생시?
    • 클라우드면 일단 서버부터 늘리고, 이후에 튜닝
    • 클라우드가 아니면 열심히 튜닝

 

✔️ 쓰레드 풀 - 쓰레드 풀의 적정 숫자

  • 쓰레드 풀의 적정 숫자는 어떻게 찾을까? : 대략적으로 감을 잡아야 한다.
  • 애플리케이션 로직의 복잡도, CPU, 메모리, IO 리소스 상황에 따라 모두 다르다.
  • 결국, 성능 테스트를 해보며 체크해야한다.
    • 최대한 실제 서비스와 유사하게 성능 테스트를 시도해야한다.
    • 툴 : 아파치 ab, 제이미터, nGrinder

 

✔️ WAS의 멀티 쓰레드 지원

  • 멀티 쓰레드에 대한 부분은 WAS가 처리한다.
  • 개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않아도 된다.
  • 개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 코드를 개발한다.
  • 멀티 쓰레드 환경이므로 싱글톤 객체(서블릿, 스프링 빈)는 주의해서 사용한다.

 

💡 참고
스프링 빈은 싱글톤이다.

 

profile
"야, (오류 만났어?) 너두 (해결) 할 수 있어"

0개의 댓글