[Spring MVC ] 웹 애플리케이션 이해 (1)

조대훈·2024년 2월 18일
0

김영한 Spring MVC -1

목록 보기
1/9
post-thumbnail

웹서버

웹이라는 것은 모두 HTTP를 기반으로 통신한다. 클라이언트의 웹 브라우저에서 URLd을 치면 인터넷을 통해 서버에 접근을 하고, 서버에서는 HTML을 만들어 인터넷을 통해 클라이언트에 내려준다. 잇달아 클라이언트는 HTML로 사용자의 눈 앞에 보여준다.

클라이언트에서 서버로 데이터를 전송할 때, 서버에서 클라이언트로 데이터를 내려줄 때 전부 HTTP 프로토콜을 기반으로 작동한다.

모든것이 HTTP

HTTP 메세지에 모든 것을 전송한다.

  • HTML, TEXT
  • IMAGE, 음성, 영상, 파일
  • JSON,XML

웹서버

  • HTTP 기반으로 동작하는 서버이며
  • 정적 리소스를 제공하는데 특정 폴더에 파일들을 주면 서버가 HTTP 요청에 응하여 HTTP 응답을 해준다
    - 정적(파일) HTML, CSS, JS
  • NGINX,APACHE

정적 리소스란?
특정 디렉토리에 있는 HTML, CSS , JS, 이미지, 영상 등을 서버가 파일들을 서빙해주는 것이다. 가령 index.html을 달라고 클라이언트가 요청하면 서버가 HTTP 프로토콜로 응답 해준다.

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

프로그램 코드를 실행해서 애플리케이션 로직 수행

사용자에 따라 동적으로 다른 화면을 보여줄 수 있다. 사용자의 이름이라던가, 관리자 일반 고객 등에 따라서 동적인 HTML을 생성하고 요즘 많이 쓰는 REST API도 WAS에 속한다.

  • HTTP 기반으로 동작
  • 웹 서버 기능 포함 + (정적 리소스 제공 기능)
  • 프로그램 코드를 실행해서 애플리케이션 로직 수행
    - 웹서버와 달리 사용자에 따라 달리 프로그램 코드로 보여줄 수 있다.
    - 동적 HTML, HTTP API(JSON)
    - 서블릿, JSP,스프링 MVC
  • 톰캣(Tomcat) ,Jetty,Undertow

웹서버와 웹앱 서버의 차이가 뭐지 그럼?

웹서버는 정적 리소스, WAS는 애플리케이션 로직까지

사실 둘의 경계도 모호하다. 사실 웹서버도 프로그램을 실행할 수 있다.

  • 웹 서버는 정적 리소스(파일), WAS는 애플리케이션 로직
  • 사실 둘의 경계도 모호하다.
    - 웹 서버도 프로그램을 실행하는 기능을 포함한다
    - 웹 애플리케이션 서버도 웹 서버의 기능을 제공한다
  • 자바는 서블릿 컨테이너 기능을 제공하면 WAS
    - 서블릿 없이 자바코드를 실행하는 서버프레임워크도 있음

경계가 모호하면 뭘로 구분하지?

결론 WAS는 웹앱코드를 실행하는데 더 특화되어 있다

웹 시스템 구성 WAS, DB

  • WAS, DB 만으로 시스템 구성 가능
  • WAS는 정적 리소스, 애플리케이션 로직 모두 제공 가능

WAS로만 구성시의 단점

WAS가 너무 많은 역할을 담당하게 된다. 정적인 리소스들고 제공 해야 하고 어플리케이션 로직도 제공 해야 하고 서버 과부하 우려가 있다.

정적리소스 제공은 사실 제공만 하는 것 뿐이라 서버 비용이 저렴한 편이다. 하지만 어플리케이션 로직은 정말 비용이 비싸다.

  • 가장 비싼 애플리케이션 로직이 정적 리소스 때문에 수행이 어려울 수 있음.
    -WAS 장애시 오류화면도 노출 불가능

웹시스템 구성 -WEB, WAS, DB

위에서 말한 WAS로만 구성시의 단점을 극복하기위한 일반족인 웹 서버 구조

웹서버에 정적리소스를 앞에 두고 전부 처리해버린다. 동적인 로직이 필요한 URL 이면 WAS 가 처리하고 DB에서 필요한 데이터를 꺼내 클라이언트에게 전달한다.

  • 정적 리소스는 웹 서버가 처리
  • 웹 서버는 애플리케이션 로직 같은 동적인 처리가 필요하면 WAS에 요청을 위임
  • WAS는 중요한 애플리케이션 로직 담당

웹 시스템 구성의 장점

정적 리소스가 많이 필요하면? 그에 맞춰 웹서버만 증성하면 되고, 만약에 정적 리소스가 아닌 애플리케이션 로직만 필요하면 그에 맞게 WAS만 더 늘리면 된다.

  • 정적 리소스가 많이 사용되면 Web서버 증설
  • 애플리케이션 리소스가 많이 사용되면 WAS 증설

왜 이렇게 귀찮게 따로 늘리지?

웹서버는 계산하는 로직이 많이 다루지 않고 다운되는 일이 별로 없다. WAS 서버가 다운될 시에 웹서버에서 오류 화면을 띄울 수 있다. WAS의 단점 극복

  • 정적 리소스만 제공하는 단순한 WebServer는 잘 죽지 않음
  • 애플리케이션 로직이 동작하는 WAS 서버는 잘 죽음
  • WAS, DB 장애시 WEB 서버가 오류화면 제공

서블릿

HTTP 스펙을 매우 편리하게 쓸수 있게 도와주는 도구

HTML Form 데이터 전송

POST 전송- 저장

회원 가입을 하는 POST 요청을 예시로 들어보자

웹애플리케이션 서버를 직접 다 구현해야 한다면?

전 세계 개발자가 아래 일련의 과정을 모두 개발해야 한다. 회원 가입을 하면 단지 DB에 저장하면 될 뿐인데 앞 뒤로 부수적인 일련의 과정들이 너무 많다.

어떻게 간소화 할수 있을까?
서블릿은 초록색 테두리 안에 있는 것을 제외하고 전부 다 지원 해준다.

서블릿을 지원하는 WAS가 해주는 일

위의 흐름 정도는 대략적으로 인지하고 있는 편이 좋다.

서블릿

서블릿의 생김새
/hello URL이 붙으면 웹브라우저에서 서버로 요청이 왔을 때, 서블릿 코드에 있는 service 코드가 실행이 된다.

우리 개발자가 해야 될일은 HttpServlet을 상속 받고 어노테이션에 해당 URL만 입력하고 서비스만 개발하면 된다. 소켓을 연결하고, 메세지를 파싱하고 요청을 구분하고, 응답메세지를 보내고 소켓을 닫고 하는 일련의 과정들을 전부 생략할 수 있다.

  • urlPatterns(/hello)의 URL 이 호출되면 서블릿 코드가 실행
  • HTTP요청 정보를 편리하게 사용할 수 있는 HttpServletRequest
  • HTTP 응답 정보를 편리하게 제공할 수 있는 HttpServletResponse
  • 개발자는 HTTP 스펙을 매우 편리하게 사용할 수 있다

  1. 웹 브라우저에서 localhost 해당 경로로 서버에 요청을 하면 WAS 서버에서는
  2. HTTP 요청 메세지를 기반으로 request, response 파라메터를 기반으로
  3. helloServlet을 실행 시킨다.( 해당 서비스가 있는 클래스)
  4. return을 하게 되면 response를 바탕으로 응답 메세지를 만든다
  5. 웹 브라우저에 나타난다

해당 URL에 request, response 파라메터 삼아 실행하게되면 helloServelt이 이에 상응하여 HTTP 요청과 응답을 알아서 만들어 준다

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

서블릿 컨테이너

톰캣 처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 한다
자동생성, 호출, 생명주기 관리 다 한다!

서블릿 객체는 개발자가 직접 생성하거나 하는 게 아니라 코드만 입력하면 된다.
서블릿을 지원하는 WAS안에는 서블릿 컨테이너 라는 것이 있는데, 이 안에 서블릿 객체를 서블릿 컨테이너가 자동으로 생성 해주며, 방금 처럼 호출도 해주며 WAS가 종료될 때 서블릿도 같이 종료 해주며 생명주기도 다 관리 해준다. 서블릿이 여러개 있으면 컨테이너가 여러개가 들어가게 된다.

  • 톰캣 처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 한다
  • 서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기를 관리한다.
  • 서블릿 객체는 싱글톤으로 관리
    - 처음에 딱 하나만 생성하고 모두가 공유해서 쓴다
    - 고객의 요청이 올 때 마다 계속 객체를 생성하는 것은 비효율
    - 서블릿 객체와 달리 request, response는 요청이 올때마다 생성된다
    - 최초 로딩 시점에 서블릿 객체를 미리 만들어두고 재활용
    - 모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근
    - 싱글톤 관리에 따른 공유 변수 사용 주의
    - 서블릿 컨테이너 종료시 함께 종료
  • JSP도 서블릿으로 변환 되어서 사용
  • 동시 요청을 위한 멀티 쓰레드 지원

멀티 쓰레드

트래픽이 많은 커널에 어떻게 해야할지 매우 중요한 개념

클라이언트가 서버에 요청을 하면 TCP/IP 커넥션이 연결이 된다. servlet 이라는 걸 호출 해주는데 그럼 servlet은 누가 호출을 할까?

바로 쓰레드가 servlet을 호출 한다!!!

쓰레드

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

  • 애플리케이션 코드 하나하나를 순차적으로 실행하는 것이 쓰레드
  • 자바 메인 메서드를 처음 실행하면, main이라는 이름의 쓰레드가 실행
  • 쓰레드가 없다면 자바 애플리케이션 실행이 불가능
  • 쓰레드는 한 번에 하나의 코드 라인만 수행
  • 동시 처리가 필요하면 쓰레드를 추가 생성

단일 요청- 쓰레드 하나 사용

다중 요청 - 쓰레드 하나 사용

여러가지 이유로 요청1에 쓰레드가 처리 지연 중인데 요청2가 들어왔다. 쓰레드를 쓰려면 대기해야 하는 상황이다. 결과적으로 둘 다 요청 수행을 못하고 있는 상황이 초래된다.

위와 같은 상황은 단순히 요청 마다 쓰레드를 생성하면 해결 된다.

쓰레드 1이 처리 지연중이어도 새로운 쓰레드를 생성해 처리하는 모습. 하지만 이렇게 개발하면 단점 또한 분명히 존재하는데 비용이 매우 비싸고, 서버에 부담이 된다는 점이다.

요청 마다 쓰레드 생성시
장점

  • 동시 요청을 처리할 수 있다
  • 리소스가 허용할 때 까지 처리 가능
  • 하나의 쓰레드가 지연 되어도, 나머지 쓰레드는 정상 작동한다.
    단점
  • 쓰레드 생성 비용은 매우 비싸다.
    - 고객의 요청이 올 때 마다 쓰레드를 생성시, 오히려 응답 속도가 늦어진다.
  • 쓰레드는 컨텍스트 스위칭 비용이 발생한다.
    - 여러개의 쓰레드가 있을 떄
  • 쓰레드 생성에 제한이 없다.
    - 고객 요청이 과도할 시 CPU,메모리 임계점을 넘어 서버가 죽을 수 있다.

위의 단점을 해결하기 위해 대부분의 서버는 쓰레드 풀 구조로 구성 되어 있다.

쓰레드 풀

풀 안에 미리 쓰레드를 만들어 놓고 요청이 오면 가져다 쓰는 방식이다. 스위칭 비용 등을 절감하고 쓰레드를 다 쓰고 나면 쓰레드를 죽이지 않고 풀에 반납한다.
단순히 빌려 쓰는 개념이라고 생각하면 된다. 쓰레드가 전부 실행 중일 때엔 쓰레드 대기 중이거나 거절을 한다.

요청 마다 쓰레드 생성의 단점 보완

  • 특징
    - 필요한 쓰레드를 쓰레드 풀에 보관하고 관리한다
    - 스레드 풀에 생성 가능한 쓰레드의 최대치를 관리한다. (톰캣은 최대 200개)
  • 사용
    - 쓰레드가 필요하면 이미 생성된 쓰레드 풀에서 꺼내 쓴다
    - 사용 종료시 쓰레드 풀에 쓰레드를 반납한다.
    - 기다리는 요청은 거절하거나, 특정 숫자만큼 대기하도록 설정할 수 있다.
  • 장점
    - 쓰레드가 미리 생성되어 있으므로, 생성 종료하는 (CPU) 비용이 절감되고, 응답 시간이 빠르다
    - 생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있다.

참고) 쓰레드풀 실무 팁

  • WAS의 주요 튜닝 포인트는 최대 쓰레드 이다
  • 너무 낮게 설정하면?
    - 동시 요청이 많으면 서버 리소스는 여유롭지만, 클라이언트는 금방 응답지연
  • 너무 높게 하면?
    - 동시 요청이 많으면, CPU, 메모리 소스 임계점 초과로 서버 다운
  • 장애 발생시?
    - 클라우드면 일단 서버부터 늘리고 튜닝
    - 클라우드가 아니면 튜닝

쓰레드 풀의 적정 숫자는?

  • 애플리케이션 로직의 복잡도, CPU, 메모리, IO 리소스 상황에 따라 모두 다름
    - DB를 한 번 조회하느냐, 두번 조회하느냐 등..
    - 아무리 잘하는 사람도 딱 결론 짓지 못하고 성능 테스트를 해봐야 한다..
  • 툴 : 아파치 ab, 제이미터, nGrinder

WAS의 멀티 쓰레드 지원

핵심은 WAS가 멀티쓰레드를 지원해서! 개발자는 이 부부분을 고민 할 필요가 없다

  • 멀티 쓰레드의 대부분은 WAS가 처리한다
  • 개발자가 멀티 쓰레드 관련 코드를 신경 쓰지 않아도 됨
  • 개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 코드를 개발
  • 멀티 쓰레드 환경이므로 싱글톤 객체(서블릿,스프링빈) 주의해서 사용
    - 멤버변수, 공유변수 조심

HTML, HTTP API, CSR, SSR

백엔드 개발자가 어디까지 알아야 하는지

정적 리소스

  • 고정된 HTML 파일, CSS, JS, 이미지 파일, 영상 등을 제공
  • 주로 웹 브라우저

동적 HTML 생성

WAS가 애플리케이션 로직에 따라 동적으로 HTML 생성 후 웹 브라우저에 전달

HTTP API

단순 HTML을 전달하는 게 아닌 데이터를 전달

단순히 조회가 아닌 주문 정보 조회 후 해당 주문 번호에 맞는 JSON 데이터를 내려줌

  • HTML 이 아니라 데이터 전달
  • 주로 JSON 형식 사용
  • 다양한 시스템에서 호출

  • 데이터만 주고받음
  • 앱, 웹 클라이언트, 서버to 서버

  • UI 화면이 필요하면 클라이언트가 별도 처리
  • 주로 JSON 형태로 데이터 통신

UI 클라이언트 접점

  • 앱 클라이언트(아이폰, 안드로이드,PC앱)
  • 웹 브라우저에서 자바스크립트를 통한 HTTP API 호출
  • React, Vue.js 같은 웹 클라이언트

서버 to 서버

  • 주문 서버 -> 결제 서버
  • 기업간 데이터 통신

그래서 백엔드 개발자가 서비스를 제공할 때 뭘 고민 해야 하지??

  • 정적 리소스 전달 방법
  • 동적 리소스 ( HTML 리소스 ) 전달 방법
  • HTTP API 전달 방법

서버사이드 렌더링, 클라이언트 사이드 렌더링

서버 사이드 렌더링

서버에서 최종 HTML을 생성해서 클라이언트에 전달

주문내역 주세요 라고 서버에 요청이 오면 서버는 주문 DB를 조회해서 HTML을 동적으로 생성한 다음 JPS TYPELEAF등을 통해 생성한 다음 최종적으로 HTML을 서버에서 다 만들어낸다

클라이언트 사이드 렌더링

HTML에서 최종적으로 표현할 결과들을 처음부터 서버로부터 얻는 게 아니라 자바스크립트를 사용해 웹브라우저에서 동적으로 생성해서 사용하는 것. 주로 동적으로 자주 바뀌는 값들을 표현해야 할때 쓴다.

  • SSR 서버 사이드 렌더링
    - HTML 최종 결과를 서버에서 만들어서 웹 브라우저에 전달
    - 주로 정적인 화면에 사용
    - 관련기술 JSP 타임리프
  • CSR 클라이언트 사이드 렌더링
    - HTML 결과를 자바스크립트를 사용해 웹 브라우저에서 동적으로 생성해 적용
    - 주로 동적인 화면에 사용, 웹 환경을 마치 앱 처럼 필요한 부분 부분 변경할 수 있음
    - 구글지도나 캘린더 등
    - 관련 기술 리액트, 뷰
  • 참고
    - React Vue SSR CSR을 동시에 지원하는 웹 프레임워크도 존재한다
    - SSR 을 사용하더라도 자바스크립트를 사용해 화면 일부를 동적으로 변경 가능

  1. 요청 및 응답 과정: 클라이언트 사이드 렌더링에서는 서버로부터 초기 HTML 페이지가 아닌 빈 HTML 페이지나 미리 정의된 HTML 템플릿이 내려옵니다. 이 HTML에는 주로 자바스크립트 파일들의 링크가 포함되어 있습니다. 이후 브라우저가 해당 HTML을 받으면서 자바스크립트 파일들을 요청합니다.
  2. 자바스크립트 로드 및 실행: 브라우저는 HTML을 받은 후 자바스크립트 파일들을 요청하고 받아옵니다. 이 파일들은 클라이언트 애플리케이션의 로직과 뷰 컴포넌트를 포함합니다. 이후 브라우저는 이 자바스크립트 파일들을 실행하여 동적으로 DOM을 생성하고 렌더링합니다.
  3. 데이터 요청 및 처리: 브라우저에서는 초기 HTML이나 자바스크립트 실행 후에 필요한 데이터를 서버에 요청합니다. 이는 주로 HTTP API 요청을 통해 이루어집니다. 서버는 이러한 요청에 응답하여 필요한 데이터를 JSON 형식으로 제공합니다.
  4. 클라이언트 측 렌더링: 브라우저에서는 받아온 데이터를 사용하여 클라이언트 측에서 동적으로 HTML을 생성하고 렌더링합니다. 이는 주로 자바스크립트 프레임워크 또는 라이브러리를 사용하여 이루어집니다. 데이터와 상태에 따라 화면을 업데이트하고 사용자와의 상호작용을 처리합니다.

DOM에 대한 부분은 추가로 다른 포스팅에서 상세하게 다루도록 해보자.

따라서 클라이언트 사이드 렌더링에서는 초기 HTML이나 렌더링 로직이 서버에서 제공되는 것이 아니라, 브라우저 측에서 자바스크립트를 실행하여 동적으로 생성됩니다. 이로써 사용자 경험을 개선하고 빠르고 반응성 있는 애플리케이션을 구축할 수 있습니다.

자바 웹 기술 역사

이 부분은 편하게 들으려고 했다

이전의 사용 기술

  • 서블릿 1997
    - TCP/IP 멀티 쓰레드를 연결하는 등 HTML 생성에 번거로움을 덜기 위해 등장
    - 지난 시간에 봤듯 자바 코드로 생성해야 되기 때문에 동적으로 처리하기가 매우 어렵다.
  • JSP 1999
    - 서블릿의 문제를 해결하기 위해 등장했다.
    - HTML 생성은 편리하지만, 비즈니스 로직까지 너무 많은 역할 담당
    - 파일 하나에 비즈니스 로직 까지 한 번에 하려니 파일 하나에 수천 줄이 넘어가 유지보수가 사실상 매우 어려웠다.
  • 서블릿, JSP 조합 MVC 패턴 사용
    - 모델, 뷰, 컨트롤러 역할을 나누어 개발
    - 핵심은 비즈니스 로직을 담당하는 부분과 화면을 렌더링 하는 부분을 나누는 것이다
  • MVC 프레임 워크 춘추 전국 시대 2000년 초~ 2010년 초
    - MVC 패턴도 자동화, 복잡한 웹 기술을 편리하게 사용할 수 있는 다양한 기능 지원
    - 스트럿츠, 웹워크, 스프링MVC(과거버전)

현재 사용 기술

애노테이션 기반의 스프링 MVC 등장
굉장히 편리하고 유연하게 코드 작성이 가능

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

스프링 부트의 등장

  • 스프링 부트는 서버를 내장
  • 과거에는 서버에 WAS를 직접 설치하고(Tomcat),
    - 소스코드는 또 따로 War 파일을 만들어 서버 폴더에 설치한 WAS에 배포
  • 스프링 부트는 빌드 결과 (jar)에 WAS 서버 포함 -> 빌드 배포 단순화

암튼 매우 복잡 했는데~ 매우 단순하고 간소화 되었다~

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

  • Web Servlet - Spring MVC
  • Werb Reactive - SpringWebFlux

스프링 웹 플럭스

동시에 상품 조회하고, 주문도 조회하고 API를 동시에 써서 조합을 해야되는 상황에도 함수형 스타일로 개발 하게되면 매우 처리가 용이해진다.

  • 비동기 넌 블러킹 처리?
  • 최소 쓰레드로 최대 성능 - 쓰레드 컨텍스트 스위칭 비용 효울화
  • 함수형 스타일로 개발?- 동시 처리 코드 효울화
  • 서블릿 기술 사용 X

기술적 난이도가 높고, RDB (관계형 데이터 베이스) 자원이 부족하며, MVC 쓰레드 모델도 충분히 빠르다
실무에서는 많이 사용하지 않음.

자바 뷰 템플릿 역사

HTML을 백엔드에서 편리하게 생성하는 뷰 기능

  • JSP
    - 느리고, 기능 부족
  • 프리마커, 벨로시티
    - 빠르고, 기능 다양
  • 타임리프
    - 내추럴 템플릿: HTML 모양을 유지하면서 뷰 템플릿 적용
    - HTML 태그를 사용
    - 스프링 MVC와 강력한 기능 통합
    - 최선의 선택
profile
백엔드 개발자를 꿈꾸고 있습니다.

0개의 댓글