Programming-[Backend]/Spring

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

컴퓨터 탐험가 찰리 2021. 7. 17. 13:07
728x90
반응형

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

 

HTTP와 정적 리소스

 

거의 모든 통신이 HTTP를 기반으로 한다!
HTML, TEXT, 이미지, 음성, 파일, JSON 등 대부분의 데이터가 인터넷의 HTTP라는 프로토콜(규약)을 기반으로 해서 통신한다.

정적 리소스란, 서버 컴퓨터 내에 저장되어 있는 HTML, 이미지, 영상 등으로 클라이언트에서 이런 파일에 대한 요청을 하면, 서버에서는 파일을 전송해주는 방식으로 서버를 구성한다. 클라이언트와 서버간 상호작용을 통해 정보 및 자료가 작성되는게 아니고, 단순히 서버에 존재하는 파일이기 때문에 정적 리소스라는 용어를 사용한다. 정적 리소스를 전달해주는 서버를 웹서버(WEB)라고 한다.

 

 

WEB 서버와 WAS

 

반면, 웹 애플리케이션 서버(WAS)란, 웹서버의 기능에 프로그램 코드를 실행해서 애플리케이션 로직을 수행하는 것을 말한다. 동적 HTML(사용자 마다 다르게 보이는 HTML 등), HTTP API 등을 적용할 수 있다. WAS에는 톰캣(tomcat), Jetty, Undertow 등의 종류가 있다.

 

 


사실 두 서버의 종류간 명확한 경계가 있는 것은 아니다. 다만 WAS는 애플리케이션 코드를 실행하는데 더 특화되어있는 서버를 말한다.



WEB-WAS-DB 구성
WAS가 너무 많은 역할을 담당하게 되면 서버 과부하가 발생할 수 있다. 용량이 작고 단순한 경우는 상관없지만, 정적 리소스의 용량이 너무 커서 애플리케이션 로직이 수행에 방해를 받게 되면 WAS를 통해서 오류화면을 표현하는 것조차도 불가능해지게 된다. 이렇게 서버에 이상이 생겨서 정보를 표시할 수 없으면, 사용자에게 알림 화면을 보여줄 수 없게 되는 경우가 생긴다. 그래서 WEB, WAS, DB를 아래 그림처럼 구성한다. 정적 리소스는 WEB이 처리하고, 동적인 처리가 필요한 경우에만 WAS가 처리하도록 한다. 이렇게 하면 각 서버의 부하를 줄일 수 있게 된다. 그리고 WEB은 간단히 정적 리소스를 제공하므로 장애가 잘 발생하지 않는데, WAS는 개발자가 작성한 로직이 잘못되어 장애가 발생할 확률이 상대적으로 높다. 따라서 WEB에서 WAS의 장애를 인식하고 오류화면을 클라이언트에 보여주도록 구성한다. 또한, 애플리케이션의 종류에 따라서 효율적인 자원 관리가 가능해진다. 만약 정적 리소스가 많이 필요하면 WEB을 증설하고, 애플리케이션 리소스가 많이 필요하면 WAS를 증설하면 된다.

 

 


 

2. 서블릿

 


원래는 HTTP 요청을 받기 전에, 서버에서 TCP/IP 요청을 기다리고, 소켓 연결 작업까지 해주어야 한다. 그리고 받은 HTTP 요청 메시지를 파싱해서 서버에서 해석해야 한다. 이를 바탕으로 애플리케이션 로직을 실행하고, 그 이후에 다시 응답을 위한 HTTP 메시지를 만들어 주어야 한다. 마지막으로 TCP/IP에 응답을 전달하고 소켓을 종료해주어야 한다. 그런데 이러한 작업들은 반복적이고 번거로운 작업이다. 그래서 개발자가 비즈니스 로직에만 집중할 수 있도록, 비즈니스 로직의 전후단계를 처리해주는 역할을 서블릿이 한다.

 

 


서블릿에서는 요청과 응답을 해석해주고, HTTP 스펙을 이용할 수 있도록 다양한 기능을 제공한다. 나중에 직접 작성해보겠지만, 요청은 HttpServletRequest, 응답은 HttpServletResponse 라는 객체를 통해 모든 처리를 할 수 있게 된다.

WAS 내부에서 서블릿을 지원할 수 있으며, 이것을 서블릿 컨테이너라고 한다. 서블릿 컨테이너는 서블릿 객체를 생성, 호출하여 생명주기까지 관리해준다. 서블릿의 관리 방식은 싱글톤 패턴 방식으로 한다. HTTP 요청과 응답은 각자 다른 객체가 생성되지만, 이것을 처리해주는 서블릿 객체는 싱글톤으로 작성해야 효율적이기 때문이다. 하나의 싱글톤으로 여러 요청과 응답을 처리해도 된다. 요청에 대한 응답만 맞으면 되는 것이지, 처리하는 주체가 달라질 필요는 없기 때문이다. 그리고 싱글톤 패턴이 적용되므로, 공유 변수를 사용할 때 주의하여야 한다. 이전 스프링 기초에서 배운 것처럼, 싱글톤 내에 상태값을 유지하고 있는 변수가 있다면, 해당 싱글톤 객체를 사용할 때 상태값이 유지되어 각각의 요청에 대해 독립적인 상태값을 전달해주지 못하게 된다.

추가로, 서버로 동시에 오는 요청을 처리하는 멀티 쓰레드 기능도 WAS가 지원해준다. 쓰레드는 중요한 개념이므로 다음 섹션에서 따로 다룬다.


 


3. 멀티 쓰레드

 


HTTP 요청이 오면, 서블릿을 호출하는 것은 쓰레드이다. 애플리케이션 코드를 한 줄씩 순차적으로 실행하는 주체가 쓰레드이며, 자바에서는 main 메서드를 실행하면 main이라는 이름의 쓰레드가 실행된다. 따라서 웹 서비스에서 동시 작업이 필요한 경우, 쓰레드를 추가로 생성해주어야 한다.

 


그런데, 수많은 요청에 대해서 계속해서 쓰레드를 만들어주게 되면 서버의 CPU와 메모리에 부하가 크게 걸릴 것이다. 게다가 쓰레드를 새로 생성하는 것은 비용이 큰 작업이며, 각 쓰레드를 담당하는 CPU 코어가 달라지게 되는 컨텍스트 스위칭 비용이 발생한다. 예를 들어, CPU 코어가 1개인데 작업을 요구하는 쓰레드가 2개이면, CPU는 1개 쓰레드 작업을 처리하고 나머지 쓰레드의 작업을 처리하기 위해 컨텍스트 스위칭을 한다. 따라서 쓰레드는 항상 제한 갯수가 있어야 한다. 요청에 따라 쓰레드가 몇 만개 이상이 생성되면, 서버가 다운되버릴 수 있다.

 


쓰레드풀

그래서 쓰레드풀이라는 것을 미리 생성해놓는다(톰캣의 기본 갯수는 200개). 서버에서 사용될 쓰레드의 갯수를 미리 계산하여 그만큼의 쓰레드를 미리 만들어놓는 것이다. 만약 최대 쓰레드 갯수를 넘어서면 각 요청들에 대기 또는 거절 응답을 보내는 방식을 사용한다.

 

 


 

 

4. 웹 페이지 표현 및 전송 방식

 

 

 


서버의 요청에 대한 응답은 크게 3가지 방식으로 구분할 수 있다.

 

 

  • 정적 리소스 : HTML, 이미지, 파일 등을 의미한다.
  • HTML : 동적인 HTML 방식을 의미한다.
  • HTTP API : 백엔드-프론트엔드가 문자로된 데이터(객체, 배열, 리스트, 문자열, 숫자 등 텍스트로 이루어진 정보)만 주고받는 형식으로, 다양한 시스템에서 사용할 수 있다. 데이터의 양식으로는 주로 JSON 형식을 사용한다. 웹브라우저상 UI가 필요하면 클라이언트가 별도로 처리한다(프론트엔드). WAS - 웹 클라이언트, WAS - 앱 클라이언트, WAS - WAS 간에 서로 데이터를 주고받는 곳에서 쓰인다.

 

 



서버사이드 렌더링(SSR)


서버에서 HTML을 생성하고 요청에 대한 응답으로 전송하는 것을 의미한다. 주로 정적인 화면을 구성하는데 사용하며, JSP, 타임리프 등을 활용한다.



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

클라이언트-서버간 통신 결과를 바탕으로 웹 브라우저에서 자바스크립트를 사용하여 동적인 HTML을 만들어서 사용하는 것을 의미한다. 웹 페이지의 각 부분을 따로 변경할 수 있다(SPA, Single Page Application).

 

 

 

 


 

참조

 

1. 인프런_스프링 MVC 1편 - 백엔드 웹개발 핵심 기술_김영한 님 강의

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1

728x90
반응형