BE/SPRING

[Spring] 스프링 MVC 1편 1.웹 어플리케이션 이해

hyu_na 2024. 3. 14. 21:21

(1) 웹서버, 웹 어플리케이션 서버 

1. HTTP 메시지에 모든 것을 전송 

http를 기반으로 모든 형태의 데이터 전송이 가능 

-html, text

-이미지,음성,영상,파일

-json, xml(api)

 

2.웹서버, 웹 어플리케이션 서버

웹서버 - http를 기반으로 동작하는 서버, 정적 리소스 제공

 

웹 어플리케이션 서버 [WAS]

- http를 기반, 프로그램 코드를 실행해 어플리케이션 로직 수행

- 동적 html 생성 , http api(json) 제공 가능

- servlet, jsp, spring mvc 가 WAS에서 동작

 

차이점 

-경계 모호함

-WAS 는 어플리케이션 코드 실행에 더 특화된 서버 정도 

 

3.웹 시스템 구성 

WAS + DB 만으로 구성 가능 

WAS는 정적 리소스, 어플리케이션 로직 모두 제공 가능하므로 

BUT//  WAS의 서버 과부화 우려 *WAS는 장애시 오류 화면 노출도 불가능 

 

=>> 보통 WEB server + WAS + DB로 구성 

정적리소스는 웹 서버에서 *오류화면 출력 가능

어플리케이션 로직만 WAS에서 담당 

 

API만 제공하는 API 서버를 구축할 경우 웹서버 없이 WAS만으로 구성해도 됨

 

 

(2) 서블릿

0. html form 데이터 전송 

웹브라우저가 post 방식의 http 요청 메시지를 만들어 서버로 전송

 

1.서버에서 처리해야 하는 업무 

WAS를 직접 구현시 

-서버에 TCP/IP 연결 대기 후, 연결이 들어오면 소켓을 연결하도록 함

-HTTP 요청 메시지는 단순 텍스트 -> parsing을 통해 post 방식과 save URL 인식

-Content-type을 확인하고, 이에 따라 메시지 바디의 내용도 parsing

-저장에 대한 비즈니스 로직 실행, 데베에 저장 요청 **의미있는 비즈니스 로직

-저장 결과를 웹 브라우저에 전달하기 위해 HTTP 응답 메시지를 직접 생성 

-TCP/IP로 HTTP 응답 메시지를 전달하고 소켓을 종료함

 

=의미있는 로직 수행 전 후 로 단계가 너무 많아 비효율적

 

=> 서블릿을 지원하는 WAS 사용

-서블릿은 의미있는 비즈니스 로직을 제외한 모든 작업을 지원해, 서블릿을 지원하는 WAS에서는 TCP/IP 연결, HTTP 요청 메시지 파싱, HTTP 응답 메시지 생성까지 자동화됨 

 

 

2.서블릿

코드 *HttpServlet 상속

@WebServlet(name="helloServlet",urlPatterns="/hello")
public class HelloServlet extends HttpServlet{
	@Override
    protected void service(HttpServletRequest request,HttpServletResponse response){
    	//어플리케이션 로직
    }
}

 

-urlPatterns(/hello)의 URL이 호출되면 해당 서블릿 코드가 실행됨 

-HTTP 요청/응답 정보를 편리하게 사용할 수 있는 HttpServletRequest, HttpServletResponse 사용

HttpServiceRequest : 객체에 파싱된 HTTP 요청 메시지의 내용이 들어있음

HttpServletResponse : 객체에 원하는 데이터를 넣으면 HTTP 응답 메시지를 생성할 수 있음

 

 

HTTP 요청 시 응답 흐름

 

 

 

3.서블릿 컨테이너 

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

 

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

-작성한 서블릿 객체를 개발자가 생성할 필요 x 

 

고객의 요청이 올 때마다 계속 객체 생성x (비효율) => 싱글톤으로 관리

- Request, Response 객체는 클라이언트 요청시 마다 생성하는 것이 맞음

-하지만 어플리케이션 로직을 작동시키는 서블릿 객체는 재사용함 

-최초 로딩 시점에 서블릿 객체를 미리 생성 후 서블릿 컨테이너 종료시 함께 종료

-모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근하므로, 공유 변수 사용에 주의

 

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

동시 요청을 위한 멀티스레드 처리 지원

 

 

(3) 동시 요청 - 멀티 스레드 

1. 스레드

클라이언트에서 서버로 요청 메시지를 보내면 WAS가 응답

이때, TCP/IP connection이 연결되고, WAS가 서블릿 호출

 

이 서블릿을 호출하는 게 스레드 

 

어플리케이션 코드를 하나하나 순차적으로 실행하는 것이 스레드

- 스레드는 한번에 하나의 코드 라인만

- 스레드가 없다면 자바 어플리케이션 실행 불가능 

 

자바 메인 메소드를 처음 실행하면 main 스레드가 실행됨 

동시 처리가 필요하면 스레드를 추가로 생성함 

 

 

1.1 스레드 하나 사용

WAS 내에 스레드가 한 개 있다고 가정

 

 

1.1.1 단일 요청

클라이언트로부터 요청이 하나 오면, 하나 있는 스레드가 할당되어 서블릿 코드를 실행함 

응답을 수행 한 후에는 다시 휴식 상태로 

 

1.1.2 다중요청

스레드는 하나인데 여러개의 요청이 들어오는 경우, 차례대로 스레드 할당 되어 서블릿 코드 실행

 

1번 요청 처리가 잘 되면, 순차적으로 2번 요청에 대한 응답 수행

but, 1번 요청을 처리하는 과정에 서블릿 코드 내부의 이유로 인한 지연이 발생

 

 

이 지연 발생 중 2번 요청이 들어온다면, 스레드가 하나뿐이므로 대기 

 

지연이 길어지면 1번,2번 연결 모두 죽어버려 2번 요청에 대한 수행 자체가 불가

 

=>

1.2 요청마다 스레드 생성 

다중 요청시 스레드를 하나 더 생성하고 동일한 서블릿을 호출해 2번 요청을 처리

 

이처럼 요청이 오면 스레드를 생성하고, 요청이 끝나면 스레드를 종료하는 식으로 WAS를 구현해도 됨

 

1.2.1 장점

- 동시 요청 처리 가능

- 리소스 (cpu, memory)가 허용될 때까지 요청 처리 가능

- 하나의 스레드가 지연되더라도, 나머지 스레드는 정상 동작 가능

 

1.2.2 단점

- 스레드 생성에 cpu 많이 사용됨 -> 고객의 요청이 올 때마다 스레드를 생성하면 응답속도 느려짐

- cpu core에서 각 스레드를 전환시 context switching 비용 발생 *스레드가 많아질수록 높은 비용

- 스레드 생성에 제한이 없으며, cpu/memory 임계점이 넘으면 서버 죽을 수도 

 

 

 

=>

2. 스레드 풀

1.2의 단점을 보완하는 방법으로 대부분의 WAS 구현 방식 

 

 

2.1 특징

- 필요한 스레드를 스레드 풀에 보관하고 관리 

- 스레드 풀에 생성 가능한 스레드의 최대치를 관리함 

*스프링 부트에서 사용하는 톰캣 - 기본 설정 200개 (변경가능)

 

 

2.2 사용

- 스레드가 필요할 때마다 스레드 풀에 요청해, 이미 생성되어 잇는 스레드를 받아 사용

- 스레드 사용을 종료하면 반납 *스레드를 종료하는 것 xx

- 최대 스레드가 모두 사용중이어서 스레드 풀에 스레드가 없는 경우 요청을 거절 or 대기하도록 설정

 

2.3 장점

- 스레드가 미리 생성되어 있으므로, 스레드를 생성하고 종료하는 비용이 절약되어 응답 시간이 빠름

- 생성 가능한 스레드의 최대치가 정해져있으므로, 많은 요청이 들어와도 스레드 풀이 감당할 수 있는 만큼만 안전하게 처리 가능 

 

2.4 tip 

- WAS의 주요 튜닝 포인트 : 최대 스레드 수

- 낮게 설정 -> 서버 리소스는 여유/ 클라이언트는 잦은 응답 지연 = 비효율

- 높게 설정 -> cpu/memory 리소스 임계점 초과로 서버 다운 

 

- 장애 발생시, 

클라우드 환경 - 일단 서버부터 늘려서 서비스는 살리고 튜닝 

클라우드 환경 x - 튜닝 

 

**적절한 최대 스레드 수 찾기 

*실제 서비스와 유사한 성능테스트 시도해야함

 

3. WAS의 멀티 스레드 지원

멀티스레드에 대한 부분은 WAS가 처리해 개발자가 신경 xx

(싱글 스레드 프로그래밍하듯 개발하면 됨 

 

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

 

 

 

 

(4) HTML, HTTP API, CSR, SSR

1. 정적 리소스, HTML 페이지, HTTP API

*백엔드 개발자가 서비스를 제공할 때 고민해야되는 포인트 세가지

 

1.1 정적 리소스 

정적 리소스 제공시, 고정된 HTML 파일, css, js image,video 등 제공

- 요청이 들어오면 웹 서버가 이미 생성되어있는 리소스를 조회해 반환함 

 

 

1.2 HTML 페이지

동적으로 필요한 HTML 파일을 생성해서 전달하는 방식 

 

-요청이 들어오면, 어플리케이션 로직을 수행할 수 있는 WAS가 데이터베이스를 조회

- 조회한 데이터를 바탕으로 동적으로 HTML을 생성해 클라이언트에 전달

* HTML 생성에 JSP, 타임리프 등 뷰 템플릿 사용

웹브라우저는 HTML 해석 (렌더링)

 

 

1.3  HTTP API

HTML이 아니라 주로 JSON 형식을 사용해 데이터를 전달하는 방식 

 

-요청이 들어오면, 어플리케이션 로직을 수행할 수 있는 WAS가 데이터 베이스를 조회 

- 조회한 데이터를 바탕으로 JSON 형식의 데이터를 생성해 클라이언트에 전달 

 

데이터만 주고 받으며 UI 화면 필요시, 클라이언트가 별도 처리 

 

앱, 웹 클라이언트, 서버 2 서버 등 다양한 시스템에서 호출 

앱 클라이언트- 데이터를 받아 앱의 UI 컴포넌트를 이용해 사용자에게 뷰 제공

웹 클라이언트- 데이터를 받아 React, Vue.js 같은 웹 클라이언트를 이용해 사용자에게 뷰 제공 

서버 2 서버 - HTML 필요 없이 데이터만 주고 받으면 됨 

*기업 간 데이터 통신 시 *요즘 한 기업 안에서도 여러 서비스들이 쪼개져 있고, 각 서버는 HTTP API로 통신 

 

 

 

2. SSR, CSR

2.1 SSR 서버 사이드 렌더링 

서버에서 HTML 최종 결과를 만들어 클라이언트에 전달하는 방식 

- 주로 정적인 화면에서 사용 

- 관련 기술 : JSP, thymeleaf

- ssr을 사용하더라도, js를 사용해 화면 일부를 동적 변경 가능

 

 

- 요청이 들어오면, 어플리케이션 로직을 수행 할 수 있는 WAS가 데이터베이스 조회 

- 조회한 데이터를 바탕으로 동적으로 HTML을 생성해 클라이언트에 전달 

*서버에서 JSP,thymeleaf 같은 뷰템플릿 사용해서 HTML 생성

 

2.2 CSR 클라이언트 사이드 렌더링 

클라이언트에서 js를 사용해 HTML 결과를 동적으로 생성해 적용하는 방식 

-관련 기술 : React, Vue.js

-  React, Vue.js를 csr + ssr 동시 지원하는 웹 프레임워크도 존재 

 

주로 동적인 화면에 사용해 앱처럼 필요한 부분부분 변경 가능 

ex) google map, gmail

 

1. 웹 브라우저가 서버에 HTML을 요청하면, 서버는 응답으로 어플리케이션을 구동하는 js 링크를 제외하면 텅 빈 HTML 정송

<!-- Html -->
   <html>
     <head>
       ...
     </head>
     <body>
       <div id="root"></div>
       <script src="app.js"></script>
     </body>
   </html>

 

2. 응답을 받은 웹 브라우저는 js를 요청하고, 서버는 클라이언트 로직과 HTML 렌더링 코드가 담긴 js코드를 전송

3. 웹 브라우저는 HTTP API를 이용해 서버를 호출하고, 서버는 데이터베이스를 조회해 얻은 값을 JSON형식으로 전송

4. 웹 브라우저는 클라이언트 로직, HTML 렌더링 코드, HTTP API를 통해 전송받은 데이터를 이용해 동적으로 렌더링

 

 

 

 

(5) 자바 백엔드 웹 기술 역사

1. 자바 웹 기술 역사 

1.1 과거 기술

- 서블릿 : 자바 코드를 사용해 HTML을 동적으로 생성하기 어려움

- JSP : HTML 생성은 편리하나, 비즈니스 로직까지 너무 많은 역할을 부여  *코드가 수천줄이 넘어가며 유지/보수가 어려워짐

- 서블릿 + JSP 의 MVC 패턴 : 모델, 뷰, 컨트롤러로 역할을 나누어 개발 

 

-> MVC 프레임 워크 시대 

   - MVC 패턴 자동화, 복잡한 웹 기술을 편리하게 사용할 수 있는 다양한 기능 지원

   - 스트럿츠, 웹위크, 스프링 MVC 

 

 

1.2 현재 사용하는 기술

- 어노테이션 기반의 스프링 MVC가 등장

- 서버가 내장된 스프링 부트의 등장

* 스프링 부트는 스프링을 사용하며 불편한점들을 자동화 

* 빌드 결과(jar)에 WAS 서버가 포함되어 있어, 빌드/배포의 단순화가 이루어짐 

 

 

1.3 최신 기술 

-Web Servlet - Spring MVC 

* 스프링 MVC는 기본적으로 서블릿을 기반으로 동작

* 동시 처리를 위한 멀티 스레드 지원 

* 현재 실무에서 대부분 사용 

 

- Web Reactive - Spring WebFlux

 * 비동기 논블로킹 처리

 * 최소 스레드로 최대 성능을 발휘해, 스레드 컨텍스트 스위칭 비용 최소화 

 * 함수형 스타일 -> 동시 처리 코드를 효율화

 * 서블릿 기술을 사용하지 않음

 

** 웹 플럭스의 기술적 난이도 매우 높으나 일반 MVC 스레드 모델도 충분히 빠름

** 웹 플럭스의 관계형 데이터베이스 지원은 아직 부족 -> 아직 많이 사용 x

 

 

 

2. 자바 뷰 템플릿 역사 

- 뷰 템플릿은 HTML을 편리하게 생성하는 View 기능 

 

- JSP : 속도 느리고 기능 부족 

- 프리마커(Freemarker), 벨로시티(Velocity) : 속도 문제 해결, 다양한 기능

- 타임리프(Thymeleaf) * 최선 

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

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

 : 단, 성능 자체는 프리마커, 벨로시티 보다 느림