스프링 웹 MVC

최은창·2024년 3월 30일
post-thumbnail

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


웹은 다 HTTP 프로토콜 기반으로 다 통신한다. 여기에는 HTML, TEXT, 이미지, 음성, API 데이터 등 거의 모든 형태의 데이터 전송이 가능하다.

웹 서버(Web Server)

웹 서버는 HTTP 기반으로 동작하는 서버이며 정적 리소스를 제공한다.
정적 리소스란 HTML, CSS, JS, 이미지 등 이런 데이터를 정적 리소스라 하며 웹 서버는 HTTP 프로토콜을 이용하여 위 데이터를 제공한다.
웹서버에는 는 NGINX, APACHE등이 있다.

웹 애플리케이션 서버(WAS)


WAS는 HTTP 기반으로 동작하고 웹 서버가 제공하는 기능과 더불어 동적 HTML을 제공한다. → 와스는 코드를 실행하여 애플리케이션 로직을 수행할 수 있다.
또한 WAS에서는 동적 HTML, HTTP API(JSON), REST API, 서블릿, JSP, 스프링 MVC, 톰켓 등 실행 할 수 있다.

웹 서버와 WAS의 차이

사실 둘의 경계는 모호하지만 크게 보면 웹 서버는 정적 리소스(파일)을 제공하고 WAS는 애플리케이션 로직을 제공한다. 웹 서버도 플러그 인을 설치하여 프로그램을 실행할 수 있고 WAS도 웹 서버의 기능을 제공한다.
그리고 자바는 서블릿 컨테이너 기능을 제공하면 WAS가 되며 요즘은 서블릿 없이 자바 코드를 실행하는 서버 프레임워크도 있다.
그래서 그냥 WAS는 애플리케이션 코드를 실행하는데 더 특화 되어 있다고 정의 하면 된다.

웹 시스템 구성 - WAS,DB

웹 시스템을 WAS와 DB로만 구성하면 WAS는 정적 리소스와 애플리케이션 로직 제공에 모든걸 담당해야된다. 이는 작은 시스템에서는 구축이 가능하지만 큰 시스템에서 문제가 있다.
WAS는 오류 화면 노출을 할 수 없는데 만약 서버에 과부하가 생기면 클라이언트는 오류 여부를 확인하기 어렵게 된다.

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

가장 일반적인 방법으로 WEB - WAS - DB 방법을 사용한다. 정적 리소스 처리는 웹 서버가 담당하고 동적 처리는 WAS가 담당한다. 웹 서버에서 동적 처리를 WAS에게 요청하고 만약 WAS가 로직을 처리하지 못하는 기술적 오류가 발생하면 웹 서버가 클라이언트한테 오류 화면을 제공할 수 있다.(WAS는 잘 죽는데 웹 서버는 생각보다 잘 안죽음)
이 구성을 통해 효율적인 리소스 관리를 할 수 있다 만약 정적 리소스를 많이 사용한다면 웹 서버만 증설하면 되고 애플리케이션 리소스를 많이 사용한다면 WAS만 더 증설하면 된다.

요즘에는 CDN 정적 리소스를 캐시할 수 있는 중간 서버를 놓고 발전하고 있다.또한 데이터만 주고 받을때는 WAS만 있어도 된다!

서블릿

HTML FROM을 이용하여 데이터를 전송할때 웹 브라우져는 HTML 폼을 참고하여 요청 HTTP 메시지를 만든다. 만약 우리가 WAS를
직접 구현해야 한다면 바닥부터 요청 메시지와 로직 수행 후 응답 메시를 모두 직접 구현해야된다.

서블릿을 통해 WAS 구현


서블릿을 통해 WAS를 구현하게 된다면 요청 메시지부터 응답 메시지까지 모든걸 개발자가 만들 필요가 없이 비지니스 로직만 제작하면 된다.

서블릿을 사용하면 개발자는 요청에 맞는 서비스 로직을 수행하는 클래스를 만들고 HTTP 서블렛만 상속 받으면 된다. 이후 파싱된 객체를 통해 값을 불러와 로직을 만들면 된다.

  • ex) 파싱된 객체를 통해 값을 불러오는 방법



    request.get.age → 20 얻는다.

WAS 서버에서 Requse객체와 Response 객체를 만들고 요청 메시지를 기반으로 request 객체에 정보를 담아 둔다. 그 다음 서블릿 객체를 호출하고 우리가 만든 helloServlet 로직을 실행 후 request 객체를 뒤지며 Response객체에 응답 정보를 리턴해준다. 이후 응답 객체를 참고해 WAS는 응답 메시지를 만든 후 웹 브라우저에 전달해준다.

참고 : WAS 안에는 서블릿 컨테이너가 있다 서블릿 컨테이너는 서블릿 객체를 생성해주며, 호출, 생명 주기 관리를 해준다.

정리하자면 톰켓처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 한다. 서블릿 컨테이너는 서블릿 객체를 생성하고 초기화 및 호출 종료 하는 생명주기를 관리한다. 또한 서블릿 객체는 싱글톤으로 관리되며 동시 요청을 위한 멀티 쓰레드 처리 지원도 가능하다

💡주의!
서블릿 객체는 싱글톤으로 관리되기 때문에 공유 변수, 멤버 변수 사용에 주의 해야한다! reponse, request객체는 요청이 올때마다 항상 새로 생성된다 하지만 서블릿 컨테이너의 서블릿 객체는 새로 생성되지 않는다. → 재사용

멀티 쓰레드


애플리케이션 코드를 하나하나 순차적으로 실행하는 것을 쓰레드라고 한다. 쓰레드가 없다면 자바 애플리케이션 실행이 불가능하며 쓰레드 하나당 하나의 코드라인만 수행 가능하다. 만약 다중 처리가 필요하면 다중 쓰레드가 필요하다.

만약 쓰레드 하나만 사용한다면 쓰레드가 하나의 요청을 처리도중 다른 요청은 처리할 수 가 없게된다. 이 상태에서 처리중이던 작업이 지연이 된다면 대기중이던 요청도 계속 대기하게 된다. 그렇게 되면 TIME-OUT 으로 두 요청은 죽게 된다.

요청 마드 쓰레드 생성

요청이 올때마다 쓰레드를 투입시키는게 가장 좋은 방법이다. 그러면 동시 요청을 처리할 수 있으며 리소스(CPU, 메모리)가 허용할 때 까지 처리가 가능하다. 또한 하나의 쓰레드가 지연되어도, 나머지 쓰레드는 정상 작동하기때문에 다른 요청들이 처리를 기다리다가 TIME-OUT으로 죽게 될 걱정이 없다.

대신 쓰레드는 생성 비용이 매우 비싸다(자원-CPU를 많이쓴다.) 만약 무수한 요청마다 쓰레드가 생성이되면 응답 속도가 매우 늦어지게 된다. 또한 쓰레드는 컨텍스트 스위칭 비용이 많아진다. 또한 쓰레드 생성은 제한이 없으므로 만약 주구장창 생성이 되면 자원의 한도를 넘어 서버가 죽을 수 있다.

쓰레드 풀

쓰레드 풀은 요청이 올때 마다 쓰레드 생성의 단점을 보완한다. 필요한 쓰레드를 쓰레드 풀에 보관하고 관리하며 생성 가능한 쓰레드의 최대치를 관리한다. (톰켓은 기본값이 200이다) 만약 쓰레드가 필요하면 이미 생성되어 있는 쓰레드를 쓰레드 풀에서 꺼내 사용하고 사용을 종료하면 쓰레드 풀에 해당 쓰레드를 반납한다. 또한 최대 쓰레드가 모두 사용중이여서 쓰레드 풀에 쓰레드가 없다면 기다리는 요청을 거절하거나 특정 숫자 만큼 대기하도록 설정할 수 있다.
이러한 쓰레드 풀의 장점은 쓰레드가 미리 생성되어 있으므로, 쓰레드를 생성하고 종료하는 비용(자원)이 절약되고, 응답 시간이 그때그때 생성한것보다 빠르다. 또한 생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청을 안전하게 처리할 수 있다.

실무 팁

실무에서는 WAS의 주요 튜닝 포인트는 최대 쓰레드의 수를 설정하는 것이다.

  • 쓰레드 풀이 너무 낮게 설정되면?
    동시 요청이 너무 많으면, 서버 리소스(자원 등)는 여유롭지만, 클라이언트는 금방 응답 지연 현상을 겪게 될것이다. → 이런경우 CPU는 50% 정도는 써줘야 한다
  • 이 값을 너무 높게 설정하면?
    동시 요청이 많으면, CPU, 메모리, 리소스 등의 임계점이 초과되며 서버가 다운 될 수 있다.
  • 장애 발생시
    클라우드에서 장애가 발생한거면 일단 서버를 먼저 늘록, 이후에 쓰레드 풀의 값을 튜닝하면 된다.

그럼 적정 숫자는 어떻게 찾을까?
이는 애플리케이션 로직의 복잡도(DB 접근등) CPU, 메모리, IO 리소스 상황에 따라 모두 다르기에 성능 테스트를 통해 최대한 실제 서비스와 유사하게 테스트릴 시도해서 병목 포인트를 찾아서 튜닝을 해야 된다!

WAS의 멀티 쓰레드 지원

쓰레드 풀이나 이런 멀티 쓰레드에 대한 부부는 WAS가 처리해줄 수 있다. 그렇게 되면 개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않아도 된다.(→concurrency 공부를 따로 안해도 된다.) 개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 코드를 개발하면 된다. 대신 멀티 쓰레드 환경이므로 싱글톤 객체(서블릿, 스프링 빈-공유변수, 멤버변수 등)에 대하 사용에는 주의랄 해야된다.

HTML, HTTP API, CSR, SSR

백엔드 개발자가 서비스를 제공할때 고민해야되는 3가지 포인트
1. 정적 리소스를 어떻게 제공할지
2. 동적으로 제공되는 HTML 페이지를 어떻게 제공할지
3. HTTP API를 어떻게 제공할지

  • 정적 리소스
    고정된 HTML 파일, CSS, JS, 이미지, 영상등을 제공하는 리소스이며 주로 웹 브라우저를 말한다.

  • HTML 페이지
    동적으로 필요한 HTML 파일을 생성해서 전달하며 DB와 로직으로 동적 HTML을 생성한 후 웹 브라우저에 보낸다.

  • HTTP API
    HTML이 아니라 데이터를 전달하며 주로 JSON형식으로 사용한다. 또한 HTTP API는 다양한 시스템에서 사용된다. → 고민 포인트 3가지를 HTTP를 통해 데이터를 주고받을떈 다 고민해야된다.

  • SSR - 서버 사이드 렌더링
    서버에서 최종 HTML을 생성해서 클라이언트에 전달하는 것으로 주로 정적인 화면에 사용한다.

  • CSR - 클라이언트 사이드 렌더링
    HTML 결과를 자바스크립트를 사용해 웹 브라우저에서 동적으로 사용해서 생성해서 적용하며 주로 동적인 화면에 사용한다. 또한 웹 환경을 마치 웹 처럼 필요한 부분부분을 URL을 변경하지 않고 변경할 수 있다.(ex 맵)

profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

0개의 댓글