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

윤경·2021년 9월 4일
1

Spring MVC

목록 보기
1/26
post-thumbnail

드디어 스프링부트 기초, HTTP 기본을 마치고 스프링 MVC를 배우러 왔습니다. ㅎㅇㅌ!!
스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술


[1] 웹 서버, 웹 애플리케이션 서버

우리가 어제까지 왜 HTTP를 배웠을까?

모든 것이 HTTP이기 때문이다 !

HTTP에는 모든 것을 담아 전송할 수 있다. (ex. HTML, TEXT, IMAGE, 파일, JSON, XML(API)..)
거의 모든 형태의 데이터를 전송한다. 서버간 데이터를 주고받을 때도 대부분 HTTP를 사용한다.

웹 서버 Web Server

HTTP 기반으로 동작하며 정적 리소스를 제공한다.
정적 리소스라 함은 HTML, CSS, JS, 이미지, 영상 .. (ex. NGINX, APACHE)

가장 큰 특징은 정적 리소스를 제공해 특정 사용자마다 다른 화면을 보여준다던지.. 이런 기능을 수행할 수 없다.

웹 애플리케이션 서버 WAS

: Web Application Server
(와스라고 부르며) HTTP 기반으로 동작한다.
웹 서버 기능을 포함하며 정적 리소스를 제공할 수 있다.

웹 서버와는 다르게 프로그램 코드를 실행해 애플리케이션 로직을 수행한다. (ex. 동적 HTML, HTTP API(JSON) (=rest api), 서블릿, JSP, 스프링, MVC)
그래서 사용자마다 다른 화면을 제공할 수 있다.

Web Server 🆚 WAS

웹 서버는 정적 리소스(파일), WAS는 애플리케이션 로직을 수행한다.

사실 둘 용어의 경계부터가 모호하다. 웹 서버도 프로그램을 실행하는 기능을 포함하기도 하며, 웹 애플리케이션 서버도 웹 서버의 기능을 제공한다.

자바는 서블릿 컨테이너 기능을 제공하면 WAS.
WAS는 애플리케이션 코드를 실행하는데 더 특화되어 있다.

웹 시스템 구성

WAS, DB만으로도 시스템을 구성할 수 있다.

WAS는 정적 리소스, 애플리케이션 로직 모두 제공할 수 있다.
그래서 WAS가 너무 많은 역할을 담당하게 되어 서버 과부하가 우려된다.

html, css, js, 이미지 같은 것은 값이 싸고 단순한데 애플리케이션 로직은 비싸다. 이러한 로직이 정적 리소스 때문에 수행이 어려워질 수 있다. (WAS는 생각보다 잘 죽는다.)
그 래 서 웹 서버가 중간에 있어야 한다. ⬇️ 이렇게 중간에 웹 서버가 있으면 정적 리소스는 웹 서버가 처리해주고 애플리케이션 로직같은 동적인 처리는 WAS에게 요청을 위임해버리면 된다.

WAS는 중요한 애플리케이션 로직 처리 전담

효율적인 리소스 관리가 된다. (정적 리소스가 많이 사용되면 웹 서버를 증설하고 애플리케이션 리소스가 많이 사용되면 WAS를 증설하면 된다.)

정적 리소스만 제공하는 웹 서버는 잘 죽지 않으며 상대적으로 잘 죽는 WAS가 죽게되면 웹 서버가 오류 화면을 제공해주면 된다.


[2] 서블릿

: 클라이언트의 요청을 처리하고, 그 결과를 반환하는 서블릿 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술 (?)
간단히, 자바를 사용하여 웹을 만들기 위해 필요한 기술

POST 전송으로 저장을 수행하려면 서버에서는 (웹 애플리케이션 서버를 직접 구현했을 땐) 이 박스에 있는 모~든 일을 (취소선으로 표시된 모든 것들을) 수행해야 한다. 하지만 서블릿을 지원하는 WAS를 사용하면 이렇게 초록 박스의 의미있는 비즈니스 로직만 수행하면 된다.

  • urlPatterns(/hello)의 URL이 호출되면 서블릿 코드가 실행된다.
  • HTTP 요청 정보를 편리하게 사용할 수 있는 HttpServletRequest
  • HTTP 응답 정보를 편리하게 제공할 수 있는 HttpServletResponse
    (이 객체들에 원하는걸 넣기만 하면 됨)

➡️ 개발자는 HTTP 스펙을 매우 편리하게 사용할 수 있게 되었다. (그래도 http 기본은 알고 써야한다.)

➡️ HTTP 요청시 WAS는 Request, Response 객체를 새로 만들어 서블릿 객체를 호출한다.
개발자는 Request, Response 객체에 HTTP 요청, 응답 정보를 편리하게 꺼내고 입력해 사용할 수 있다.
그리고 WAS는 Response 객체에 댐긴 내용을 기반으로 HTTP 응답 정보를 생성한다.

서블릿 컨테이너


: 톰캣처럼 서블릿을 지원하는 WAS

📌 특징

서블릿 객체는 싱글톤으로 관리된다. 처음에 딱! 하나만 생성해놓고 모두가 공유해 사용한다.
고객의 요청이 올 때마다 계속 객체를 생성하는 것은 비효율적이다.
(request, response객체는 요청이 올 때마다 (username처럼) 다 다른 것이라 새로 만드는 것이 맞지만, helloServlet은 굳~이 새로 생성할 필요가 없다는 것이다.)

최초 로딩 시점에 서블릿 객체를 미리 만들어두고 계속 재활용한다. 즉, 같은 서버라면 모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근하게 된다.

그래서 공유 변수 사용에 주의해야 한다. (윤경으로 로그인했는데 춘배의 이름이 보일 수도 있다 ,,;)

서블릿 컨테이너 종료시 서블릿 객체가 함께 종료된다.

JSP도 서블릿으로 변환되어 사용된다.
동시 요청을 위한 멀티 쓰레드 처리를 지원한다.


[3] 동시 요청 - 멀티 쓰레드

쓰레드

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

자바 메인 메소드를 실행하면 main이라는 이름의 쓰레드가 실행되는 것이며 쓰레드가 없다면 자바 애플리케이션 실행 자체가 불가능하다.

쓰레드는 한 번에 하나의 코드 라인만 수행하며 동시 처리가 필요하면 쓰레드를 추가 생성한다.

단일 요청이 들어왔을 때 쓰레드를 하나 사용하는 경우를 살펴보자.

🤷🏻 그렇다면 다중 요청이 들어왔을 땐 어쩌지 ??

그렇다면 그냥 쓰레드를 하나 더 생성해버리자 !!

🤔 요청이 올 때마다 쓰레드를 생성해도 괜찮은걸까,,?

동시 요청을 처리할 수 있고 리소스(CPU, 메모리)가 허용할 때까지 처리할 수 있으니 좋은거 아닌가?
하나의 쓰레드가 지연된다고 해도 나머지 쓰레드가 정상 작동하니까 완전 ㄱㅇㄷ 아냐?

그치만, 쓰레드는 CPU도 너무 많이 쓰고 생성 비용이 너무 비싸다. 특히 고객 요청이 올 때마다 생성을 하게된다면 응답 속도가 점점 느려지겠지 ??

또한 코어가 하나고 쓰레드가 두 개면 코어 하나가 동시에 수행 하는 것이 아니라 빠르게 전환해가며 동작하기 때문에 우리 눈엔 동시에 수행되는 것처럼 보인다. 그렇다면 스위칭 비용이 들지 않을까 ??

맞다. 컨텍스트 스위칭 비용이 어마어마하게 커질 것이다.
그리고 또 문제가 있다. 수강신청처럼 요청이 엄청 들어올 때면 쓰레드 생성에 제한이 없기 때문에 CPU, 메모리 임계점을 넘어 서버가 그냥 죽어버릴 수도 있다.

쓰레드 풀

그 래 서 !! 내부에 쓰레드 풀이라는 것을 사용한다.


쓰레드 풀은 요청마다 쓰레드를 생성하는 단점을 보완한다.

필요한 쓰레드를 쓰레드 풀에 보관, 관리하며 생성 가능한 쓰레드의 최대치를 관리한다. (톰캣은 최대 200개가 기본으로 설정되어 있으며 변경할 수 있다.

쓰레드가 필요하다면 미리 생성되어 있던 쓰레드를 쓰레드 풀에서 꺼내 사용하면 되고 사용을 종료하면 다시 쓰레드 풀에 반납하기만 하면 된다.

만약, 모든 쓰레드가 사용 중이라면 대기를 주거나 거절할 수도 있다. (음식점을 생각해보면 된다.)

📌

WAS의 주요 튜닝 포인트는 최대 쓰레드 (max thread) 수
만약 이 값을 너무 낮게 설정한다면 그렇다고 또 너무 높게 설정해버리면 동시 요청이 많을 경우 서버 다운이 일어날 수 있다.

일단 장애가 발생하면 (클라우드라면) 서버부터 늘리고 이후 튜닝을 하도록 하자. (클라우드가 아니라면) 바로 열심히 튜닝을 해야한다 !!

🙋🏻‍♀️ 대체 쓰레드 풀의 적정 수는 어떻게 찾아야 하는거죠 ??

애플리케이션 로직의 복잡도, CPU, 메모리, IO 리소스 상황에 따라 모두 다르기 때문에 (특히 트래픽이 꽤 있는 경우라면) 성능 테스트 를 해야한다.
(성능 테스트: 최대한 실제 서비스와 유사하게 성능 테스트 시도)

정리

  • 멀티 쓰레드에 대한 부분은 WAS가 처리하기 때문에 우리는 코드 안에 비즈니스 로직만 넣으면 된다.
  • 즉, 개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않아도 된다.
  • 개발자는 마치 싱글 쓰레드를 프로그래밍 하듯 편하게 소스 코드를 개발하면 된다 !
  • 멀티 쓰레드 환경이므로 싱글톤 객체(공유 변수)는 주의해 사용하자.

[4] HTML, HTTP API, CSR, SSR

정적 리소스

: 고정된 HTML 파일, CSS, JS, 이미지, 영상 등 제공하며 주로 웹 브라우저를 말한다.

HTML 페이지

: 동적으로 필요한 HTML 파일을 생성해 전달하며 웹 브라우저가 HTML을 해석한다.

HTTP API

: HTML이 아니라 데이터를 전달한다.(데이터만 주고받는다. UI 화면이 필요하다면 클라이언트가 별도로 처리한다.)
주로 JSON 형식을 사용하며 다양한 시스템에서 호출한다.
UI 클라이언트 접점은 앱 클라이언트와 웹 브라우저에서 자바 스크립트를 통한 HTTP API 호출 두 가지가 있다.

서버 to 서버에서도 많이 사용한다. (ex. 주문 서버 → 결제 서버)

"정적 리소스는 어떻게 제공할거야?"
"동적으로 제공되는 html 페이지 어떻게 적용할거야?"
"http api 어떻게 제공할거야?

👩🏻‍💻 이 놈들이 백엔드 개발자가 해야하는 고민에 해당한다.

SSR, CSR

SSR: 서버 사이드 렌더링

HTML 최종 결과를 서버 !!에서 만들어서 웹 브라우저에게 전달한다.
주로 정적인 화면에 사용하며 JSP, 타임리프 같은 기술을 사용한다. (백엔드 개발자가 다룸)

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

HTML 결과를 자바 스크립트를 사용해 웹 브라우저 !!에서 동적으로 생성해 적용한다.
주고 동적인 화면에 사용하며 웹 환경을 마치 앱처럼 필요한 부분부분 변경할 수 있다. 동적으로 부분부분 바뀌게 함
React, Vue.js가 관련 기술에 해당한다. (프론트 개발자들이 주로 다룸)

🤷🏻 우린 대체 어디까지 알아야 하는거죠 ,,?

백엔드는 서버 사이드 렌더링 기술 !!을 꼬옥 공부하자!!
타임 리프를 요즘 스프링에서 밀고있기 때문에 이제 막 공부하기 시작한 순개들은 타임 리프를 공부하자.

웹 프론트엔드는 클라이언트 사이드 렌더링 기술을 꼬옥 공부하자!!
프론트는 리액트가 시장 점유율이 훨 높으니까 리액트를 공부하자.

우린 선택과 집중 이 필요하다. 백엔드 개발자에게 프론트 공부는 그저 옵션이다. 서버, DB, 인프라 등등 공부할게 많으니까 백엔드에 빡!! 집중하도록 하자.


[5] 자바 백엔드 웹 기술 역사

  • 서블릿 (1997)
    자바 코드로 짜야해서 HTML 생성에 어려움을 겪었다.

  • JSP (1999)
    HTML 생성은 편리하지만, 비즈니스 로직까지 너무 많은 역할을 담당하다보니 JSP 파일이 수천줄이 되고 엉망진창이 되어 MVC 패턴이 등장했다.

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

(👥👤👥(아무나): 어라 뭔가 비슷한걸? 그럼 프레임워크를 만들자 !!)
MVC 프레임워크 춘추 전국 시대 (2000초 ~ 2010초)

MVC 패턴 자동화, 복잡한 웹 기술을 편리하게 사용할 수 있는 다양한 기능을 지원
스트럿츠, 웹워크, 스프링 MVC(과거버전) 이것들을 통합한 것이 애노테이션 기반의 스프링 MVC

현재 사용 기술

  • 애노테이션 기반의 스프링 MVC
    이로인해 스프링 프레임워크가 제공하는 스프링 MVC 이기 때문에 통합에 대한 고민을 없앨 수 있었다.
    (@Controller)

  • 스프링 부트의 등장
    (: 스프링을 편리하게 사용할 수 있도록 도와주는 (아~주 많은 기능을 가진) 껍데기,,(?))

스프링 부트는 서버를 내장하고 있다.
(과거에는 톰캣 서버를 설치하고 직접 따로 실행 시켜놓고 소스 코드는 따로 빌드해 실행하고 .. 배포하는 폴더에 넣고 ...그리고 드디어 배포 ..! ➡️ 복잡.. 번거롭..)

스프링 부트는 빌드 결과(Jar)에 WAS 서버를 포함했다. (빌드할 때 톰캣을 넣어버림(?)) ➡️ 빌드 배포 단순화

스프링 웹 기술의 분화

  • Web Servlet - Spring MVC (는 서블릿 기반으로 동작. 멀티 쓰레드 가능)
  • Web Reactive - Spring WebFlux (완전 최신 기술)

✔️ WebFlux
비동기 none 블로킹 처리.
최소 쓰레드로 최대 성능을 낸다. cpu 코어 수에 맞춰 사용해 쓰레드 컨텍스트 스위칭 비용에 효율적이다.
상품 서버 조회, 주문 서버 조회... 여러가지를 가져와 조합 해야할 때 함수형 스타일로 개발하면 굉장히 깔끔해진다. ➡️ 함수형 스타일로 개발하면 동시처리 코드 효율화
서블릿 기술을 사용하지 않는다.

하지만 기술적 난이도가 너무 높고 관계형 데이터 베이스를 쓰기 어렵다. 또한, 요즘은 장비가 좋아 일반 MVC 쓰레드 모델로도 충분히 빠르기 때문에 실무에서 거의 사용하지 않는다. ^ ^;

자바 뷰 템플릿

: HTML을 편리하게 생성하는 뷰 기능

  • JSP
    : 속도 느림. 기능 부족

  • Freemarker, Velocity
    : 속도가 굉장히 빠르고 다양한 기능을 가졌지만 발전이 더디다.

  • Thymeleaf
    : 내추럴 템플릿(HTML의 모양을 유지하며 뷰 템플릿 적용 가능)
    스프링 MVC와 강력한 기능 통합
    최선의 선택임 !!. 성능은 프리마커, 벨로시티가 빠르지만 웬만~한 사이트들에겐 타임리프가 문제될 부분이 없어 타임리프를 쓰는 것이 좋다 !!


profile
개발 바보 이사 중

0개의 댓글