스프링(Spring) 및 자바(JAVA)

스프링 부트 개념 정리 - 이론10

Dev.99_tale 2025. 3. 11. 02:05

서블릿 객체의 생명주기가 궁금해요!

서블릿 객체(Servlet)와 쓰레드(Thread)란?

"서블릿은 클라이언트의 요청을 처리하는 자바 객체이고, 쓰레드는 이를 병렬로 실행하는 작업 단위이다!"

 

📌 서블릿 컨테이너, 쓰레드 관리, 그리고 서버 확장 기법

이번 글에서는 서블릿 컨테이너(Servlet Container)의 역할, 쓰레드(Thread)와 객체 재사용 원리, 그리고 **서버 확장 전략(Scaling)**에 대해 정리하겠습니다.


 서블릿(Servlet) 객체란?

"클라이언트 요청을 처리하는 자바 기반의 웹 컴포넌트!"

📌 서블릿의 특징
✅ 웹 브라우저의 요청을 처리하고 응답을 반환
✅ 최초 요청 시 한 번만 생성되며, 이후에는 재사용됨
✅ 여러 요청을 동시에 처리하기 위해 쓰레드(Thread)를 활용

📌 "서블릿은 요청이 들어오면 실행되며, 쓰레드를 통해 동시 요청을 처리한다!"


 쓰레드(Thread)란?

"프로그램 내에서 독립적으로 실행되는 작업 단위!"

📌 쓰레드의 특징
 멀티쓰레드(Multi-Threading) 방식으로 동작
✅ 여러 개의 요청을 동시에 처리 가능
 쓰레드 풀(Thread Pool)을 활용하여 재사용 가능

📌 "서블릿 하나만 있어도 여러 개의 쓰레드가 생성되어 동시 요청을 처리할 수 있다!"


 서블릿 컨테이너(Servlet Container)란?

"클라이언트 요청을 받아 서블릿(Servlet)을 실행하고, 쓰레드를 생성하여 요청을 처리하는 역할을 하는 소프트웨어 환경!"

📌 서블릿 컨테이너의 역할
✅ 클라이언트 요청(Request) 수신
✅ 서블릿 객체(Servlet) 생성 및 실행
✅ 요청을 처리할 쓰레드(Thread) 생성
✅ 처리 결과를 클라이언트에게 응답(Response)

📌 "서블릿 컨테이너는 클라이언트 요청을 효율적으로 처리하고, 서블릿과 쓰레드를 관리하는 핵심 요소!"


 톰캣(Tomcat)과 웹 서버(Apache) 차이

"정적인 파일은 웹 서버(Apache)가 처리하고, 동적인 요청은 톰캣(Tomcat)이 처리한다!"

📌 톰캣과 웹 서버 비교

구분 웹 서버(Apache) 서블릿 컨테이너(Tomcat)
처리 방식 HTML, CSS, JS 같은 정적 파일 처리 자바 서블릿(Servlet), JSP 같은 동적 요청 처리
작동 방식 요청된 파일을 그대로 반환 요청을 분석 후 서블릿을 실행하고 HTML로 변환
예제 요청 index.html, style.css user/login, product/list (JSP, Servlet)

📌 "정적인 파일은 Apache, 동적인 요청은 Tomcat이 처리한다!"


 URL vs URI – 차이점 간단 정리

"URL은 자원의 '위치'를, URI는 자원의 '식별자'를 의미한다!"

구분 설명 예시
URL (Uniform Resource Locator) 특정 자원의 위치(주소) 를 나타냄 https://example.com/index.html
URI (Uniform Resource Identifier) 자원의 식별자 (위치 포함 가능) /users/123, mailto:user@example.com

📌 "모든 URL은 URI이지만, 모든 URI가 URL은 아니다!"


 스프링은 URI를 사용한다

"스프링에서는 파일 경로(URL)를 직접 요청하지 않고, URI를 통해 자원을 식별하여 처리한다!"

📌 스프링에서는 정적 파일(URL)이 아닌, URI를 통해 요청을 처리한다!

❌ URL 요청: `https://example.com/images/logo.png`
✅ URI 요청: `https://example.com/api/users/1`

📌 "스프링에서는 URL이 아닌 URI를 사용하여 컨트롤러에서 요청을 처리한다!"

 요청 처리 흐름 – 서블릿과 쓰레드(Thread)의 역할

"클라이언트 요청이 들어오면, 서블릿 컨테이너는 서블릿 객체와 쓰레드를 사용해 요청을 처리한다!"

🔹 서블릿 요청 처리 과정

1️⃣ 클라이언트가 요청(Request) 보냄
2️⃣ 서블릿 컨테이너가 요청을 수신
3️⃣ 서블릿 객체 생성 (최초 요청 시 1번만 생성됨)
4️⃣ 새로운 쓰레드(Thread) 생성 후 요청을 처리
5️⃣ 응답(Response) 반환 후 쓰레드 재사용 (Thread Pool)

📌 "최초 요청 시 서블릿 객체가 생성되며, 이후에는 동일한 객체를 재사용한다!"

 


 서블릿 생명주기와 주요 메서드 (init(), service(), doGet() 등)

"서블릿은 생성 → 요청 처리 → 종료의 과정을 거치며, 각각의 단계에서 특정 메서드가 호출된다!"

 


 서블릿의 생명주기(Lifecycle)

"서블릿은 클라이언트 요청을 처리하기 위해 특정 메서드를 실행하며, 최초 실행부터 종료까지 다음과 같은 흐름을 따른다!"

🔹 서블릿 동작 과정

1️⃣ 클라이언트 요청 발생 (Request)
2️⃣ 서블릿 컨테이너가 서블릿 객체를 생성 (init() 호출)
3️⃣ 요청에 따라 service() 메서드 실행 (doGet(), doPost() 등 호출)
4️⃣ 응답을 반환 (Response)
5️⃣ 서버가 종료되거나 필요하지 않으면 destroy() 메서드 호출 → 서블릿 종료

📌 "서블릿은 요청이 처음 발생할 때만 생성되며, 이후에는 같은 객체를 재사용한다!"


 서블릿의 주요 메서드

"서블릿은 생명주기에 따라 init(), service(), doGet(), doPost() 등의 메서드를 실행한다!"

🔹 init() – 서블릿 초기화 (최초 요청 시 1번만 실행)

  • 서블릿이 처음 로드될 때 1번만 실행되는 초기화 메서드
  • 설정값을 불러오거나, DB 연결을 설정할 때 사용
@Override
public void init() throws ServletException {
    System.out.println("서블릿 초기화 - init() 실행!");
}

📌 "서블릿이 처음 요청될 때 한 번만 실행되며, 이후에는 다시 실행되지 않는다!"


🔹 service() – 요청을 받아 적절한 메서드로 전달

  • 모든 HTTP 요청(GET, POST 등)을 처리하는 중앙 메서드
  • 클라이언트가 요청하면 doGet(), doPost() 같은 메서드를 호출
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    System.out.println("요청 처리 - service() 실행!");

    if (req.getMethod().equals("GET")) {
        doGet(req, res);
    } else if (req.getMethod().equals("POST")) {
        doPost(req, res);
    }
}

📌 "service()는 요청이 들어올 때마다 실행되며, 적절한 메서드(doGet(), doPost())를 호출한다!"


🔹 doGet() – GET 요청 처리 (조회 요청)

  • GET 방식의 HTTP 요청을 처리
  • 보통 데이터 조회 시 사용됨
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();
    out.println("<h1>GET 요청 처리</h1>");
}

📌 "클라이언트가 GET 방식으로 요청하면 doGet()이 실행된다!"


🔹 doPost() – POST 요청 처리 (데이터 등록/변경 요청)

  • POST 방식의 HTTP 요청을 처리
  • 보통 데이터 생성, 업데이트 요청 시 사용됨
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();
    out.println("<h1>POST 요청 처리</h1>");
}

📌 "클라이언트가 POST 방식으로 요청하면 doPost()가 실행된다!"


 서블릿 생명주기 정리

메서드 실행 시점 실행 횟수 역할
       
init() 서블릿이 처음 로드될 때 한 번만 실행 서블릿 초기화
service() 클라이언트가 요청할 때마다 여러 번 실행 요청을 적절한 메서드로 전달
doGet() GET 요청이 들어올 때 여러 번 실행 데이터 조회 처리
doPost() POST 요청이 들어올 때 여러 번 실행 데이터 등록/수정 처리
destroy() 서블릿이 종료될 때 한 번만 실행 리소스 정리

📌 "서블릿은 init()으로 초기화되고, service()를 통해 요청을 받아 doGet(), doPost() 등의 메서드로 분기 처리된다!"


 쓰레드(Thread)와 쓰레드 풀(Thread Pool) 개념

"매 요청마다 쓰레드를 새로 생성하지 않고, 미리 만들어진 쓰레드를 재사용하여 성능을 최적화한다!"

🔹 쓰레드 풀(Thread Pool) 작동 원리

  • 최대 동시 요청 개수만큼 미리 쓰레드 생성
  • 새로운 요청이 오면 기존 쓰레드를 재사용
  • 동시 요청이 많아질 경우, 쓰레드 풀 최대 개수를 초과하면 대기 상태로 전환

📌 "서버는 필요할 때마다 쓰레드를 새로 생성하는 것이 아니라, 기존 쓰레드를 재사용하여 리소스를 절약한다!"


🔹 쓰레드 풀의 장점

기존 방식 (쓰레드 생성 & 제거) 쓰레드 풀 (Thread Pool)
요청이 올 때마다 쓰레드를 새로 생성 미리 생성된 쓰레드를 재사용
쓰레드 생성 & 제거 비용 큼 성능 최적화, 리소스 절약
요청이 많아질수록 서버 부하 증가 정해진 개수 내에서 효율적으로 관리

📌 "쓰레드 풀을 사용하면 요청 처리 속도를 최적화할 수 있다!"


 동시 요청 한계 – 최대 쓰레드 수 설정

"서버는 동시 요청을 처리할 수 있는 최대 쓰레드 개수를 설정하여 부하를 조절한다!"

🔹 동시 요청 개수 예제

 최대 쓰레드 수: 20개
 동시 접속자 수: 25명

1️⃣ 처음 20명의 요청은 즉시 처리됨
2️⃣ 추가 5명은 대기 상태로 전환됨
3️⃣ 기존 요청이 완료되면, 대기 중인 요청을 처리

📌 "최대 동시 요청 개수를 초과하면 일부 요청은 대기 상태가 된다!"


 서버 성능 확장 전략 – 스케일 업 vs 스케일 아웃

"트래픽이 많아질 경우, 성능을 확장하는 방법에는 스케일 업(Scale Up)과 스케일 아웃(Scale Out)이 있다!"

🔹 스케일 업(Scale Up)

  • 서버 성능을 업그레이드하여 더 많은 요청을 처리
  • CPU, RAM, 네트워크 성능을 향상

📌 "더 강력한 하드웨어로 서버를 업그레이드하여 성능을 높이는 방법!"


🔹 스케일 아웃(Scale Out)

  • 서버 개수를 늘려서 트래픽을 분산
  • 여러 대의 서버가 동시에 요청을 처리 (로드 밸런싱 적용)

📌 "여러 대의 서버를 추가하여 트래픽을 분산 처리하는 방법!"


 스케일 업 vs 스케일 아웃 비교

방식 설명 장점 단점
스케일 업 서버 성능을 업그레이드 간단한 적용, 추가 장비 불필요 하드웨어 한계 존재
스케일 아웃 서버 개수를 늘려 트래픽 분산 무한 확장 가능, 로드 밸런싱 적용 가능 서버 관리 비용 증가

📌 "트래픽이 많아질 경우, 일반적으로 스케일 아웃(Scale Out) 방식을 선호한다!"


🔥 핵심 정리

개념 설명
서블릿 컨테이너 서블릿 객체와 쓰레드를 관리하는 환경 (예: 톰캣)
웹 서버(Apache) 정적 파일(HTML, CSS, JS) 처리
톰캣(Tomcat) 자바 서블릿(Servlet), JSP 같은 동적 요청 처리
쓰레드(Thread) 요청을 병렬로 처리하는 작업 단위
쓰레드 풀(Thread Pool) 미리 생성된 쓰레드를 재사용하여 성능 최적화
최대 동시 요청 개수 설정된 쓰레드 개수를 초과하면 일부 요청은 대기
스케일 업 (Scale Up) 서버 성능을 업그레이드하여 처리량 증가
스케일 아웃 (Scale Out) 여러 대의 서버를 추가하여 트래픽 분산

📢 마무리

서블릿 컨테이너는 클라이언트 요청을 처리하기 위해 서블릿 객체와 쓰레드를 관리하는 역할을 합니다.
📌 쓰레드 풀(Thread Pool)을 사용하면 서버의 성능을 최적화할 수 있으며,

📌 트래픽 증가 시 스케일 업(Scale Up) 또는 스케일 아웃(Scale Out) 전략을 활용하여 확장할 수 있습니다!