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

peeerr·2023년 1월 29일
0

Spring

목록 보기
9/10
post-thumbnail

이 글은 김영한님의 스프링 MVC 1편 강의를 수강하고 정리한 내용입니다.
강의 보러가기


📌 1. 웹 서버와 웹 어플리케이션 서버

1) 웹은 HTTP를 기반으로 통신한다.

  • 클라이언트에서 서버로 데이터를 전송할 때, 서버에서 클라이언트로 데이터를 응답할 때 모두 HTTP 프로토콜을 기반으로 통신한다.

  • 거의 모든 형태의 데이터를 전송할 수 있다.

2) 웹 서버 (Web Server)

웹서버

  • HTTP 기반으로 동작한다.

  • 정적인 HTML, CSS, JS, 이미지, 영상 같은 리소스들을 제공한다.
    대표적으로 Nginx, Apache가 있다.

3) 웹 애플리케이션 서버 (WAS - Web Application Server)

WAS

  • 웹 서버와 마찬가지로 HTTP 기반으로 동작한다.

  • 웹 서버의 기능을 포함하고 있으며 애플리케이션 로직을 수행할 수 있다는 특징이 있다.
    대표적으로 Tomcat, Jetty, Undertow가 있다.

4) 그래서 둘이 뭔 차인데?

  • 이 두 용어의 경계는 모호하다. 웹 서버도 프로그램 코드를 실행하는 기능을 포함하기도 하며 WAS도 웹 서버의 기능을 제공하기 때문이다.

  • 간단하게 웹 서버는 정적 리소스를 제공하는 것, WAS는 애플리케이션 로직까지 수행할 수 있는 것이라고 기억해 두자.

5) 웹 시스템 구성

WAS, DB만으로 웹 시스템을 구성한다면?
wasdb

  • 앞에서 말했듯 WAS가 정적 리소스, 애플리케이션 로직까지 모두 제공이 가능해 WAS와 DB만으로도 웹 시스템을 구성할 수 있다.

  • 하지만 이 경우는 WAS가 너무 많은 일을 담당하고 있어 서버 과부하의 위험이 있다.
    WAS에 장애가 생길 경우 오류 화면조차 제공이 불가능하므로 심각한 문제가 될 수 있다.

WEB, WAS, DB로 웹 시스템 구성!
web

  • 웹 서버가 정적 리소스를 처리, WAS가 애플리케이션 로직을 처리하게끔 역할을 분담한다.

    • 효율적으로 리소스를 관리할 수 있다.

      • 정적 리소스가 많이 사용된다면 웹 서버 증설
      • 애플리케이션 리소스가 많이 사용된다면 WAS 증설
    • 복잡한 로직이 동작하는 WAS가 잘 죽기 때문에 WAS, DB 장애 시 웹 서버가 오류 화면을 제공할 수 있다.


📌 2. 서블릿


1) 서블릿 도입의 배경

이전에 어떤 문제가 있었을까?

problem

  • 서블릿의 도입 전에는 HTML Form으로 POST 요청을 보낼 경우 위 그림의 업무들을 개발자가 모두 개발해야 했었다.

서블릿이 도입되면서 초록색 박스를 제외한 나머지 업무는 자동으로 처리가 되었다.

2) 서블릿의 특징

@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
    @Override
	protected void service(HttpServletRequest request, HttpServletResponse response) {
		//애플리케이션 로직
	}
}
  • HTTP 요청 메시지를 직접 파싱해서 사용하는 건 너무 번거로운 일이다.

    • /hello URL이 호출되면 서블릿 코드가 실행되어
      HTTP 요청/응답 정보를 편리하게 사용 및 제공할 수 있는 기능을 제공한다.
      (나중에 자세히 설명)
  • 개발자가 HTTP 스펙을 편리하게 다룰 수 있게 해준다.

3) HTTP 요청, 응답 흐름

flow

HTTP 요청/응답 흐름

  1. WAS가 request, response 객체를 만들어 서블릿 객체를 호출한다.

  2. 개발자는 request / response에서 각각 HTTP 요청/응답 정보를 편리하게 사용할 수 있다.

  3. WAS는 response 객체에 담겨있는 내용으로 HTTP 응답 정보를 생성한다.

  4. 웹 브라우저에 응답 메시지가 전달된다.

서블릿 컨테이너란?

  • 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 한다.

  • 서블릿 컨테이너가 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기를 관리해준다.

  • 서블릿 객체는 싱글톤으로 관리가 된다.

    • 고객의 요청이 들어올 때마다 객체를 생성하는건 매우 비효율적이다.

    • 최초 로딩 시점에 서블릿 객체를 미리 만들어두고 재활용한다.

    • 모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근한다.

      • 공유 변수 사용에 주의
    • 서블릿 컨테이너 종료 시 서블릿 객체도 같이 종료된다.

  • JSP도 서블릿으로 변환되어 사용된다

  • 동시 요청을 위한 멀티 쓰레드 처리를 지원한다.

📌 3. 동시 요청 - 멀티 쓰레드


rr

  • 이제 클라이언트가 서버에 요청하면 WAS에서 서블릿 객체를 호출하는 것까진 이해가 된다.
    그렇다면 이 서블릿 객체를 대체 누가 호출해 주는 것일까?

1) 쓰레드

💡 바로 이 쓰레드가 서블릿 객체를 호출해 준다.

  • 애플리케이션 코드를 하나하나 순차적으로 실행하는 것이 쓰레드이다.

  • 자바 메인 메서드를 처음 실행하면 main이라는 이름의 쓰레드가 실행된다.

  • 쓰레드가 없다면 자바 애플리케이션 실행이 불가능하다.

  • 쓰레드는 한번에 하나의 코드 라인만 수행한다.

  • 동시 처리가 필요하면 쓰레드를 추가로 생성한다.

그럼 이제 쓰레드를 사용한 요청/응답 과정을 생각해 보자.

경우 1) 쓰레드를 하나만 사용

re

❓ 어떤 문제가 발생할까?

먼저 클라이언트 요청1이 들어오면 쓰레드가 서블릿 객체를 호출해 요청1을 처리한다.
그런데 그 처리가 어떠한 이유로 지연이 되는 사이에 요청2가 들어왔다고 가정하자.
요청2는 요청1의 처리가 끝날 때까지 기다려야 되는 문제가 발생하는 것이다.

그럼 위에 적혀 있듯 동시 처리가 필요한 상황이니
요청마다 쓰레드를 생성해서 처리하면 되는거 아니야?


경우 2) 쓰레드를 요청마다 생성

rth

  • 요청1 처리가 지연되는 동안 요청2는 신규 쓰레드를 생성해 처리를 진행하면서 문제가 해결되었다.

  • 위 방식에는 장단점이 존재한다.

장점

  • 동시 요청을 처리할 수 있다.

  • 리소스(CPU, 메모리)가 허용할 때까지 처리가 가능하다.

  • 하나의 쓰레드가 지연 되어도, 나머지 쓰레드는 정상 동작한다.

단점

  • 쓰레드는 생성 비용은 매우 비싸다.

    • 고객의 요청이 올 때 마다 쓰레드를 생성하면 응답 속도가 늦어진다.
  • 쓰레드는 컨텍스트 스위칭 비용이 발생한다.

  • 쓰레드 생성에 제한이 없다.

    • 고객 요청이 너무 많이 오면, CPU, 메모리 임계점을 넘어서 서버가 죽을 수 있다.

컨텍스트 스위칭 비용이란?

예를 들어 CPU 코어수가 4개라고 가정해보자.
코어는 쓰레드를 동시에 수행하지 못하기 때문에 여러 쓰레드를 번갈아가며 수행한다.
이렇게 다른 쓰레드로 전환할 때 발생하는 비용을 컨텍스트 스위칭 비용이라고 한다.

WAS에서는 쓰레드를 요청마다 생성할 때의 단점을 보완할 수 있는
쓰레드풀 이라는 것으로 구현이 되어있다.


2) 쓰레드 풀

pool

쓰레드 풀이란?

특징

  • 필요한 쓰레드를 쓰레드 풀에 보관하고 관리한다.

  • 쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리한다.
    -> 톰캣은 최대 200개가 기본 설정이다.  (변경 가능)

사용 방식

  • 쓰레드가 필요하면, 이미 생성되어 있는 쓰레드를 쓰레드 풀에서 꺼내서 사용한다.

  • 사용을 종료하면 쓰레드 풀에 해당 쓰레드를 반납한다.

  • 최대 쓰레드가 모두 사용중이라 쓰레드 풀에 쓰레드가 없으면?

    • 기다리는 요청은 거절하거나 특정 숫자만큼만 대기하도록 설정할 수 있다.

장점

  • 쓰레드가 미리 생성되어 있으므로, 쓰레드를 생성하고 종료하는 비용(CPU)이 절약되고, 응답 시간이 빠르다.

  • 생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있다.

쓰레드 풀 실무 팁

WAS의 주요 튜닝 포인트는 최대 쓰레드(max thread)수이다.

  • 이 값을 너무 낮게 설정하면?

    • 동시 요청이 많다면, 서버 리소스는 여유롭지만 클라이언트는 금방 응답 지연

      예를 들어

      • 최대 쓰레드를 10개로 설정해둔 상태에서 요청이 100개가 들어온다고 가정해보자.

      • 그러면 응답 지연은 금방되는데 CPU는 5%밖에 사용 안하고 있는 상황이 생길 수 있다.

  • 이 값을 너무 높게 설정하면?

    • 동시 요청이 많으면, CPU, 메모리 리소스 임계점 초과로 서버 다운될 수 있다.
  • 장애 발생시?

    • 클라우드면 일단 서버부터 늘리고, 이후에 튜닝한다.

    • 클라우드가 아니면 바로 튜닝한다.


❓최대 쓰레드 적정 숫자❓

  • 애플리케이션 로직의 복잡도, CPU, 메모리, IO 리소스 상황에 따라 모두 다르다.

  • 최대한 실제 서비스와 유사하게 성능 테스트를 시도하는 방법이 있다.

    • Tool -> 아파치 ab, 제이미터, nGrinder

핵심 정리

  • 멀티 쓰레드에 대한 부분은 WAS가 처리한다.

  • 개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않아도 된다.

  • 개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 코드를 개발하면 된다.

  • 멀티 쓰레드 환경이므로 싱글톤 객체(서블릿, 스프링 빈)는 주의해서 사용해야 한다.

📌 4. HTML, HTTP API, CSR, SSR


정적 리소스

flex

-> 웹 서버에서 정적인 HTML 파일, CSS, JS, 이미지, 영상 등을 제공하면 된다.

동적인 HTML 페이지

dyna

-> WAS에서 뷰 템플릿을 가지고 동적으로 필요한 HTML 파일을 생성해서 전달한다.

HTTP API

api

  • HTML처럼 보여줄 화면을 전달해 주는 것이 아니라 데이터를 전달해 주는 방식이다.

  • 데이터 형식은 주로 JSON 형식을 사용한다.

  • 웹 브라우저에 넘겨줄 때 쓰는게 아니라 다양한 시스템에서 호출한다.
    ( 어차피 웹 브라우저는 HTML을 렌더링해서 화면을 띄워야 하는데 JSON이 들어오면 해석 못한다. )

v

  • 웹/앱 클라이언트나 서버간 통신이 필요할 때 사용한다.

  • 데이터만 주고 받는다.

HTTP API 정리

  • 주로 JSON 형태로 데이터 통신한다.

  • UI 클라이언트 접점

    • 앱 클라이언트(아이폰, 안드로이드, PC 앱)

    • 웹 브라우저에서 자바스크립트를 통한 HTTP API 호출

    • React, Vue.js 같은 웹 클라이언트

  • 서버 to 서버

    • 주문 서버 -> 결제 서버

    • 기업간 데이터 통신


1) SSR - 서버 사이드 렌더링

HTML을 만드는 과정은 서버에서 모두 끝내고, 웹 브라우저는 생성된 HTML을 렌더링한다.

ssr

  • 최종적으로 HTML을 서버에서 다 만들기 때문에 서버 사이드 렌더링이라고 불린다.

  • 주로 정적인 화면에 사용된다.

  • 관련기술: JSP, 타임리프 -> 백엔드 개발자

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

웹 브라우저에서 HTML을 동적으로 생성해 적용한다.
-> 자바스크립트 사용

csr

  • 클라이언트쪽에서 HTML을 만들기 때문에 클라이언트 사이드 렌더링이라고 불린다.

  • 주로 동적인 화면에 사용, 웹 환경을 마치 앱 처럼 필요한 부분을 변경할 수 있다.

    • 예) 구글 지도, Gmail, 구글 캘린더
  • 관련기술: React, Vue.js -> 웹 프론트엔드 개발자


📌 5. 자바 백엔드 웹 기술 역사


1) 과거 기술

  • 서블릿 - 1997
    • 자바 코드로 짜야 하기 때문에 HTML 생성이 어렵다.
  • JSP - 1999
    • HTML 생성은 편리하지만 비즈니스 로직까지 너무 많은 역할을 한다.  (이후 자세히 설명)
  • 서블릿, JSP 조합 MVC 패턴 사용
    • 모델, 뷰 컨트롤러로 역할을 나누어 개발
      -> 비즈니스 로직 부분, 화면을 렌더링 하는 부분으로 나눔
  • MVC 프레임워크 춘추 전국 시대 - 2000년 초 ~ 2010년 초
    • MVC 패턴의 도입으로 개발하는 게 다 비슷비슷하니 개발에 편리한 프레임워크를 만들기 시작한다.
    • 스트럿츠, 웹워크, 스프링MVC(구버전) 등 수많은 MVC 프레임워크가 등장했다.

2) 현재 사용 기술

  • 애노테이션 기반의 스프링 MVC 등장

    • @Controller

    • MVC 프레임워크의 춘추 전국 시대 마무리!

  • 스프링 부트의 등장

    • 스프링 부트는 서버를 내장하고 있다. (Tomcat)

    • 과거에는 서버에 WAS를 직접 설치하고, 소스는 War 파일을 만들어서 설치한 WAS에 배포했다.

    • 스프링 부트는 빌드 결과(Jar)에 WAS를 포함시켜 빌드 배포를 단순화시켰다!

3) 최신 기술

  • Web Servlet 기반의 Spring MVC          ->  보통의 경우 이걸 사용!

  • Web Reactive 기반의 Spring WebFlux   ->  기술적 난이도가 매우 높아 사용하기 어렵다.

4) 자바 뷰 템플릿

  • JSP

    • 속도 느림, 기능 부족
  • 프리마커(Freemarker), Velocity(벨로시티)

    • 속도 문제 해결, 다양한 기능
  • 타임리프(Thymeleaf)

    • 내추럴 템플릿: HTML의 모양을 유지하면서 뷰 템플릿 적용 가능

    • 스프링 MVC와 강력한 기능 통합

    • 타임리프 선택이 베스트!
      (단 성능은 프리마커, 벨로시티가 더 빠름)

profile
개발 공부

0개의 댓글