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

gyeol·2023년 8월 15일

스프링

목록 보기
20/50
post-thumbnail

김영한 님의 '스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술'을 듣고 적은 글입니다.

웹 서버, 웹 애플리케이션 서버

웹은 인터넷을 통해 서로 연결된 웹 페이지들을 의미한다. HTML로 작성되어 웹 페이지를 검색하고 브라우징 할 수 있는 기술이다.

우리는 HTTP 메시지에 모든 것을 전송할 수 있다.

  • HTML, TEXT
  • IMAGE, 음성, 영상, 파일
  • JSON, XML (API)
  • 거의 모든 형태의 데이터를 전송할 수 있음

웹 서버(Web Server)

웹 서버는 HTTP 프로토콜을 이용해 클라이언트의 요청을 받아 HTML이나 오브젝트를 전송한다. 웹 서버만으로 구축된 서버는 정적 페이지를 생성한다.

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

WAS는 웹 서버 기능을 포함하며 정적 리소스를 제공해준다. 프로그램 코드를 실행해 로직을 실행할 수 있기에 동적으로 로직을 수행할 수 있다.
예시로 서블릿, JSP, 스프링 MVC가 있다.

둘의 차이?

웹 서버는 정적 리소스를 WAS는 애플리케이션 로직을 통해 동적 리소스를 수행한다.
웹 서버도 프로그램을 실행하는 기능을 포함하기도 하고 웹 애플리케이션 서버도 웹 서버의 기능을 제공하기에 이 둘의 경계는 모호하다.

다만, WAS는 애플리케이션 코드를 실행하는데 더 특화되어 있다는 것만 기억하면 된다.

웹 시스템을 구성할 때는 WEB, WAS, DB를 이용해 구성한다.
WAS와 DB만을 이용해 웹을 구성할 수도 있지만 WAS가 너무 많은 역할을 담당해 서버가 과부하될 수 있다.

정적 리소스를 앞에 두고 다 처리하게 한다. 그러다가 동적인 처리가 필요하면 웹 서버가 뒤로 넘겨서 WAS가 처리한다. 이렇게되면 WAS는 애플리케이션 로직 처리만 수행할 수 있다.
이 로직을 통해 효율적으로 리소스를 관리할 수 있다. 정적 리소스가 많이 사용되면 WEB 서버를 증설하고, 애플리케이션 리소스가 많이 사용되면 WAS 증설하면 된다.

그리고 정적 리소스만 제공하는 웹 서버는 잘 죽지않고, 애플리케이션 로직을 동작하는 WAS 서버는 잘 죽는데 WAS와 DB 장애 시 WEB 서버가 오류 화면을 제공해준다.

서블릿

서블릿은 웹 서버에서 실행되는 작은 프로그램 단위인 JAVA 객체이며, JAVA 기반 동적 웹 컨테츠를 개발하는 기술이다. 서블릿은 의미있는 비즈니스 로직들만 수행하도록 도와준다.

HTTP 요청 정보를 편리하게 사용할 수 있는 HttpServletRequest, HTTP 응답 정보를 편리하게 제공할 수 있는 HttpServletResponse를 제공해준다.

요청이 들어오면 WAS 서버에서 request, response 객체를 생성한 후 helloServlet을 실행해준다. 끝나고 리턴하면 우리가 만든 response 객체에서 응답 정보를 생성한다. 그 후 웹브라우저가 랜더링해서 예쁘게 클라이언트에게 보여준다.

  • HTTP 요청 시 request, response 객체를 새로 만들어 서블릿 객체 호출
  • 개발자는 request 객체에서 HTTP 요청 정보를 편리하게 꺼내 사용
  • 개발자는 request 객체에서 HTTP 응답 정보를 편리하게 입력
  • WAS는 response 객체에 담겨있는 내용으로 HTTP 응답 정보 생성

서블릿 컨테이너

서블릿 컨테이너는 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 한다.
서블릿 객체는 싱글톤으로 관리된다. 요청이 올 때마다 다르기 때문에 request, response 객체는 요청마다 새로 만드는게 맞다. 하지만 helloServlet은 항상 생성할 필요 없이 로직만 만들면 되기에 항상 재사용된다. 그렇기에 싱글톤으로 만들어둔다. 이때 공유 변수 사용에 주의해야 한다.

멀티 스레드

애플리케이션 코드를 하나하나 순차적으로 실행하는 것을 스레드라고 한다. 스레드가 없다면 자바 애플리케이션 실행이 불가능할 것이다. 스레드는 한번에 하나의 코드 라인만 수행하며 동시 처리가 필요하면 스레드를 추가로 생성해야 한다.


단일 스레드일 때 다중 요청이 들어오면 동시에 처리하는 것이 아닌 요청 1이 진행중이면 요청 2는 기다려야 한다. 이렇게 되면 요청1, 요청2 모두 죽게된다.

이를 해결한 단순한 방법은 신규 스레드 하나를 생성하는 것이다. 이렇게 되면 동시 요청을 처리할 수 있고 하나의 스레드가 지연되어도 나머지 스레드는 정상 동작한다. 하지만 매번 스레드를 새로 생성하면 비용도 많이 들고 응답 속도도 늦어진다.
그리고 스레드는 컨텍스트 스위치 비용이 발생하고 스레드 생성에 제한이 없기에 CPUM, 메모리 임계점을 넘어 서버가 죽을 수 있다.

컨텍스트 스위치 비용 : 스레드는 cpu 이용한다. 다중 요청시 cpu가 한꺼번에 처리하는게 아닌 순차적으로 처리한다. 예를 들어 요청이 1에서 2로 바뀔 때 비용이 발생한다.

스레드 풀

필요한 스레드를 스레드 풀에 보관하고 관리하며 스레드가 필요하면 생성되어 있는 스레드를 스레드 풀에서 꺼내 사용한다. 사용을 종료하면 스레드 풀에 스레드를 반납한다.
만약 최대 스레드가 모두 사용 중이어서 스레드 풀에 스레드가 없으면 요청을 거절하거나 대기하도록 설정할 수 있다.

이때 중요한 것은 최대 스레드 수이다.
스레드 수를 너무 낮게도 높게도 설정하면 안된다. 낮게 설정하면 서버 리소스는 여유롭지만 클라이언트는 응답이 지연되고, 너무 높게 설정하면 CPU, 메모리 리소스 임계점 초과로 서버가 다운될 수 있다.
그래서 우리는 스레드 풀의 적정 숫자를 찾는 것이 중요하다. 아파치 ab, 제이미터, nGrinder 등의 툴을 이용해 성능을 테스트해보자.

멀티 스레드에 대한 부분은 WAS가 모두 처리하기에 개발자는 멀티 스레드 관련 코드를 신경쓰지 않아도 된다. 이때 멀티 스레드 환경이기에 싱글톤 객체는 주의해서 사용해야 한다.

HTML, HTTP API, CSR, SSR

HTML

HTML 페이지는 동적으로 필요한 HTML 파일을 생성해 전달한다. 웹 브라우저는 HTML을 해석해 클라이언트에게 보여준다.

HTTP API

HTML이 아니라 데이터를 전달해준다. HTTP API는 JSON 형식의 데이터를 내려준다. 근데 웹브라우저는 JSON을 HTML로 해석해야하는데 해석하지 못하고 그냥 json 형태로 보여준다. 그래서 HTTP API는 다양한 시스템에서 호출할 때 사용된다. 화면이 필요하면 클라이언트가 별도로 처리해야 한다.

SSR - 서버 사이드 렌더링

HTML 최종 결과를 서버에서 만들어 웹 브라우저에 전달해준다. 주로 정적인 화면에 사용된다.
관련 기술에는 JSP, 타임리프가 있다.

CSR - 클라이언트 사이더 렌더링

HTML 결과를 자바스크립트를 사용해 웹 브라우저에서 동적으로 생성해 적용한다. 주로 동적인 화면에 사용되며 웹 환경의 부분부분을 변경할 수 있다.
관련 기술에는 React, Vue.js가 있다

참고) Spring WebFlux

  • 비동기 넌 블러킹 처리
  • 최소 스레드로 최대 성능 - 스레드 컨텍스트 스위치 비용 효율화
  • 함수형 스타일 개발
  • 기술적 난이도 높음

백엔드 개발자가 고민해야 할 3가지

  1. 정적 리소스 어떻게 제공?
  2. 동적으로 제공되는 HTML 페이지 어떻게 제공?
  3. HTML API 어떻게 제공?
profile
공부 기록 공간 '◡'

0개의 댓글