[스프링 MVC 1-2] 웹 애플리케이션의 이해

cloo·2026년 7월 22일

스프링 MVC

목록 보기
1/2
post-thumbnail

심화 편 → [웹 애플리케이션 이해 — 심화]


1. 모든 통신의 토대

HTTP(HyperText Transfer Protocol)는 웹에서 서버와 클라이언트가 데이터를 주고받을 때 지키는 통신 규약이다. 클라이언트의 요청(request)과 서버의 응답(response)이 짝을 이루어 동작한다.

  • HyperText: 링크를 통해 다른 문서로 건너뛸 수 있는 텍스트. HTTP는 본래 이 하이퍼텍스트 문서(HTML)를 주고받기 위해 만들어져 이런 이름이 붙었다.
  • 지금은 HTML뿐 아니라 이미지·음성·영상·파일·JSON·XML 등 거의 모든 형태의 데이터를 HTTP로 전송한다.
  • 서버 간 데이터를 주고받을 때도 대부분 HTTP를 사용한다.

2. 웹 서버와 웹 애플리케이션 서버(WAS)

구분웹 서버WAS
담당정적 리소스애플리케이션 로직(동적)
처리 방식완성된 파일 그대로 전달코드 실행해 결과 생성
관련 기술서블릿, JSP, 스프링 MVC
예시Nginx, Apache톰캣, Jetty, Undertow

웹 서버 (Web Server)

  • HTTP 기반으로 동작하는 서버
  • 정적 리소스(HTML, CSS, JS, 이미지, 영상) 제공에 특화
  • 이미 완성된 파일을 그대로 내려주므로 빠르고 안정적
  • 예) Nginx, Apache

웹 애플리케이션 서버 (WAS)

  • HTTP 기반으로 동작하며, 웹 서버 기능을 포함(정적 리소스 제공 가능)
  • 프로그램 코드를 실행해 애플리케이션 로직을 수행 → 동적 HTML, HTTP API(JSON)
  • 관련 기술: 서블릿, JSP, 스프링 MVC
  • 예) 톰캣(Tomcat), Jetty, Undertow

둘의 차이

웹 서버는 정적 리소스(파일), WAS는 애플리케이션 로직.

용어 경계는 사실 모호하다. 웹 서버도 플러그인으로 동적 처리를 할 수 있고, WAS도 정적 리소스를 제공할 수 있다. 다만 WAS는 애플리케이션 코드 실행에 더 특화되어 있다는 것이 본질이다. 자바에서는 서블릿 컨테이너 기능을 제공하면 WAS라 부른다.

웹 시스템 구성

WAS + DB (2-tier)

  • WAS만으로 정적 리소스와 로직을 모두 처리할 수 있어 구성은 단순하다.
  • 그러나 WAS가 너무 많은 역할을 떠안아 과부하 우려가 있다. 가장 비싼 애플리케이션 로직이 정적 리소스 처리 때문에 방해받을 수 있고, WAS 장애 시 오류 화면조차 띄울 수 없다.

WEB + WAS + DB (3-tier)

  • 정적 리소스는 웹 서버가 처리하고, 동적 처리가 필요하면 웹 서버가 WAS에 요청을 위임한다.
  • WAS는 중요한 애플리케이션 로직 처리에 전담한다.
  • 이점:
    • 정적 리소스 사용이 많으면 웹 서버를, 애플리케이션 리소스 사용이 많으면 WAS를 증설 → 효율적 리소스 관리
    • 정적 리소스만 제공하는 웹 서버는 잘 죽지 않고, 로직이 도는 WAS는 상대적으로 잘 죽는다. WAS·DB 장애 시 웹 서버가 오류 화면을 대신 제공할 수 있다.

3. 서블릿

서블릿이 필요한 이유

클라이언트가 요청을 보내면 서버가 처리할 일이 매우 많다. HTTP 요청 메시지를 파싱하고, 응답 메시지를 규격에 맞게 생성하는 등 저수준 작업이 요청마다 반복된다.

서블릿은 이 번거로운 HTTP 처리를 대신 해준다. 개발자는 비즈니스 로직 작성에만 집중하면 된다.

@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 요청 시 WAS는 Request·Response 객체를 새로 만들어 서블릿을 호출하고, 개발자가 Response 객체에 담은 내용으로 WAS가 최종 HTTP 응답 메시지를 생성한다.

서블릿은 자바 진영의 기술이다. 자바 언어로 작성하고, 자바 표준으로 규격이 정해져 있으며, 자바로 만든 서블릿 컨테이너에서만 실행된다. 그래서 컨테이너가 없는 웹 서버(Nginx, Apache)에서는 서블릿이 동작하지 않는다.

서블릿 컨테이너

서블릿을 담아 관리하고 실행해주는 WAS의 핵심 부품. 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라 부른다.

  • WAS ⊃ 서블릿 컨테이너: 서블릿 컨테이너는 WAS의 일부이지 전체가 아니다. WAS는 그 위에 웹 서버 기능·JSP 엔진 등을 더 갖춘 더 큰 개념이다.
  • 톰캣은 서블릿 컨테이너 && WAS다. 핵심이 서블릿 컨테이너이고, 정적 리소스 제공과 JSP 처리를 더해 가벼운 WAS 역할을 한다.

서블릿 컨테이너의 역할
1. 서블릿 객체의 생성과 관리
2. 서블릿 생명주기 관리 (생성 → 초기화 → 호출 → 종료)
3. 요청/응답 객체 생성 — HttpServletRequest, HttpServletResponse를 만들어 서블릿에 전달

  • 서블릿 객체는 싱글톤으로 관리: 최초 로딩 시점에 만들어 재활용하며, 컨테이너 종료 시 함께 소멸. → 공유 변수 사용 주의
  1. 동시 요청을 위한 멀티스레드 처리 지원

JSP도 내부적으로는 서블릿으로 변환되어 사용된다. JSP 엔진이 JSP 파일을 서블릿 자바 코드로 번역·컴파일하며, 이 변환은 보통 최초 요청 시 한 번 일어난다.

서블릿의 동작 과정


1. 클라이언트가 URL로 요청을 보내면 HTTP 요청이 WAS에 도착한다.
2. 서블릿 컨테이너가 스레드 풀에서 놀고 있는 스레드 1개를 요청에 배정한다.
3. 컨테이너가 HTTP 요청 메시지를 파싱해 HttpServletRequest 객체를 만들고, 빈 HttpServletResponse 객체를 함께 생성한다.
4. 배정된 스레드가 두 객체를 넘기며 URL에 매핑된 서블릿의 service()를 호출한다. → doGet()/doPost() 실행 → 비즈니스 로직 수행
5. 서블릿이 결과를 response에 담으면, 컨테이너가 이를 실제 HTTP 응답 메시지로 변환해 클라이언트에 전달한다.
6. 스레드는 풀로 반납되어 다음 요청을 기다린다.

결국 자바 웹에서 화면을 만드는 모든 방식은 내부적으로 서블릿으로 수렴한다. JSP도, 스프링 MVC도 겉모습은 다르지만 밑바닥에서 실제로 도는 것은 서블릿이다. 서블릿 원리를 이해해두면 그 위에 얹힌 어떤 기술을 배우든 내부 동작이 훤히 보인다.


4. 동시 요청 — 멀티스레드

스레드는 프로세스 내부에서 실행되는 작업 단위다. 스레드가 서블릿 객체를 호출한다.

  • 애플리케이션 코드를 하나씩 순차 실행하며, 한 번에 코드 한 줄만 수행한다.
  • 자바 main 메서드 실행 시 main 스레드가 뜬다. 스레드가 없으면 자바 애플리케이션 실행 자체가 불가능하다.
  • 동시 처리가 필요하면 스레드를 추가 생성해야 한다.
  • 스레드를 궁극적으로 실행시키는 건 OS와 CPU다. WAS가 만든 스레드를 OS 스케줄러가 CPU 시간을 나눠주며 실행한다. 다만 "누가 스레드를 관리하고 서블릿을 호출하는가"의 답은 WAS(톰캣)다.

요청마다 스레드 생성 — 문제점

  • 장점: 동시 요청 처리 가능, 리소스가 허용하는 한 처리 가능, 하나가 지연돼도 나머지는 정상 동작
  • 단점:
    • 스레드 생성 비용이 비싸 응답이 느려진다
    • 컨텍스트 스위칭 비용이 발생한다
    • 생성에 제한이 없어 요청이 폭주하면 CPU·메모리 임계점을 넘어 서버가 죽을 수 있다

스레드 풀 (Thread Pool)

요청마다 스레드를 생성하는 단점을 보완한다.

  • 필요한 스레드를 미리 만들어 풀에 보관·관리하고, 생성 가능한 최대치를 정해둔다(톰캣 기본 최대 200개).
  • 스레드가 필요하면 풀에서 꺼내 쓰고, 사용 후 반납한다.
  • 풀에 여유 스레드가 없으면 대기시키거나 거절한다.

장점

  • 스레드가 미리 생성되어 있어 생성·종료 비용이 절약되고 응답이 빠르다.
  • 최대치가 있어 요청이 폭주해도 기존 요청은 안전하게 처리된다.

실무 튜닝 — 최대 스레드 수(max thread)

  • 너무 낮으면: 리소스는 여유로운데 클라이언트 응답이 지연된다.
  • 너무 높으면: 리소스 임계점 초과로 서버가 다운된다.
  • 적정값은 로직 복잡도·CPU·메모리·IO 상황에 따라 다르므로, 실제 서비스와 유사하게 성능 테스트로 찾는다. (도구: Apache ab, JMeter, nGrinder)
  • 장애 시: 클라우드면 서버부터 늘린 뒤 튜닝, 아니면 튜닝에 집중.

핵심 — WAS의 멀티스레드 지원

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

커넥터와 컨테이너의 역할 분리

톰캣 내부에서 스레드 배정과 서블릿 실행은 서로 다른 부품이 맡는다.

  • 커넥터(Connector): 네트워크 입구. TCP 연결을 받고 HTTP 메시지를 읽으며, 스레드 풀에서 스레드를 꺼내 요청에 배정한다. 스레드 풀도 커넥터 쪽에 소속된다. 프로토콜 처리(HTTP/1.1, HTTP/2)도 담당한다.
  • 컨테이너(Catalina): 배정된 스레드로 URL에 맞는 서블릿을 찾아 service()를 실행한다.

5. HTML, HTTP API, SSR, CSR

서버가 응답하는 방식은 크게 정적 리소스 제공, SSR, HTTP API(CSR용)로 나뉜다.

SSR (서버 사이드 렌더링)

  • 서버에서 최종 HTML을 완성해 클라이언트에 전달
  • 주로 정적인 화면에 사용
  • 관련 기술: JSP, 타임리프 → 백엔드 개발자 영역

CSR (클라이언트 사이드 렌더링)

  • 서버는 데이터만 주고, HTML 결과를 자바스크립트로 브라우저에서 동적으로 생성
  • 주로 동적인 화면에 사용, 웹을 앱처럼 필요한 부분만 변경 가능 (예: 구글 지도, Gmail, 구글 캘린더)
  • 관련 기술: React, Vue.js → 웹 프론트엔드 개발자 영역
  • 참고: SSR+CSR을 동시에 지원하는 프레임워크도 있고, SSR을 쓰면서 일부만 JS로 바꾸는 것도 가능하다.

HTTP API

  • 화면(UI)이 아닌 데이터만 주고받는다. 화면이 필요하면 클라이언트가 별도 처리한다.
  • 주로 JSON 형태로 통신한다.
  • 활용:
    • UI 클라이언트 접점: 앱 클라이언트(iOS·안드로이드·PC), 브라우저의 자바스크립트 호출, React·Vue 같은 웹 클라이언트
    • 서버 to 서버: 주문 서버 → 결제 서버, 기업 간 데이터 통신

백엔드 개발자가 고려할 3가지
1. 정적 리소스를 어떻게 제공할 것인가
2. 동적으로 제공되는 HTML 페이지를 어떻게 제공할 것인가
3. HTTP API를 어떻게 제공할 것인가


6. 자바 백엔드 웹 기술의 역사

과거 기술

  • 서블릿(1997): HTML 생성이 어려움
  • JSP(1999): HTML 생성은 편리하나, 비즈니스 로직까지 떠안는 문제
  • 서블릿+JSP 조합 MVC 패턴: 모델-뷰-컨트롤러로 역할을 나눠 비즈니스 로직과 화면 렌더링을 분리
  • MVC 프레임워크 춘추전국시대(2000초~2010초): 스트럿츠, 웹워크, 과거 스프링 MVC 등

현재 기술

  • 애노테이션 기반 스프링 MVC 등장(@Controller) → MVC 프레임워크 경쟁 마무리
  • 스프링 부트 등장: 서버를 내장. 과거엔 WAS를 직접 설치하고 war를 배포했지만, 스프링 부트는 빌드 결과(jar)에 WAS를 포함해 빌드·배포를 단순화

최신 — 스프링 웹 기술의 분화

  • ① Web Servlet: Spring MVC
  • ② Web Reactive: Spring WebFlux
    • 완전한 비동기 논블로킹 처리, 최소 스레드로 최대 성능(컨텍스트 스위칭 비용 효율화), 함수형 스타일
    • 서블릿 기술을 사용하지 않음
    • 한계: 기술 난이도 높음, RDB 지원 부족, 일반 MVC도 충분히 빠름, 실무 사용률 낮음(1% 이하)

자바 뷰 템플릿의 역사

HTML을 편리하게 생성하는 뷰 기능의 발전:

  • JSP: 속도 느림, 기능 부족
  • Freemarker, Velocity: 속도 문제 해결, 다양한 기능
  • Thymeleaf: 내추럴 템플릿(HTML 모양을 유지하며 뷰 템플릿 적용), 스프링 MVC와 강력한 통합 → 최선의 선택. 다만 순수 성능은 프리마커·벨로시티가 더 빠름

전체 정리

HTTP라는 토대 위에서, 정적 리소스는 웹 서버가·동적 처리는 WAS가 나눠 맡고, WAS 안의 모든 화면 생성 기술은 결국 서블릿으로 수렴하며, 그 위에 스프링 MVC가 얹혀 오늘날의 표준이 되었다. 다음에 배울 스프링 MVC가 바로 이 마지막 지점에서 출발한다.

0개의 댓글