웹 애플리케이션 이해

Jaca·2021년 10월 2일
0

웹 HTTP 기반

HTTP 메세지에 모든 것을 전송하는 시대
거의 모든 형태의 데이터 전송이 가능해졌다
서버가늬 데이터를 주고 받을 때도 대부분 HTTP를 사용한다.
지금은 대 HTTP 시대.

웹 서버

  • HTTP 기반으로 동작
  • 정적 리소스를 제공하고, 기타 부가기능을 제공한다.
  • 정적(파일) HTML, CSS, JS, 이미지, 영상

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

  • HTTP 기반으로 동작
  • 웹 서버 기능을 포함하고 정적 리소스 제공도 가능하다.
  • 프로그램 코드를 실행해서 애플리케이션 로직을 수행한다.
    • 동적 HTML, HTTP API(JSON)
    • 서블릿, JSP, 스프링 MVC

웹 서버는 정적 리소스(파일), WAS는 애플리케이션 로직을 수행한다.
사실 둘의 경계가 모호하다.
웹 서버도 프로그램을 실행하는 기능을 포함하기도 하고
WAS도 웹 서버의 기능을 제공하기도 한다.

대략적으로 둘을 구분하려면 언어마다 다르지만 자바는 서블릿 컨테이너 기능을 제공하면 WAS라고 판단할 수 있다.
WAS는 애플리케이션 코드를 실행하는데 더 특화되어 있다.

웹 시스템 구성

WAS와 DB만으로도 시스템을 구성할 수는 있다.
WAS가 정적 리소스와, 애플리케이션 로직을 모두 제공 가능하기 때문

그러나 WAS가 너무 많은 역할을 담당하게 되면 서버 과부하의 우려가 있다.
아무래도 이미지같은 정적 리소스를 처리하는 비용보다 애플리케이션 로직 처리 비용이 훨씬 높은데 정적 리소스도 WAS에서 처리하려면 부하가 커져 장애가 발생할 수도 있다.
WAS가 장애시 오류 화면 조차 노출 할수가 없다.

그래서 정적 리소스는 웹 서버가 처리하게 하고
애플리케이션 로직같은 동적 처리가 필요할때 WAS에 요청을 위임한다.
WAS는 중요한 로직만 처리 전담시키는 것이다.

효율적인 리소스 관리를 위해 정적 리소스가 많이 사용되면 웹 서버를 증설하고,
애플리케이션 리소스가 많이 사용된다면 WAS를 증설하는 식으로 유연하게 가져갈 수 있다.

서블릿

위와 같이 데이터를 전송했을 때, 우리가 직접 웹 서버를 구현해야 한다면

아래와 같은 프로세스를 거쳐야 한다.
하지만 서블릿을 사용하게 되면 초록색 박스를 제외한 모든 단계를 서블릿이 지원해준다.

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

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

서블릿 컨테이너

톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 한다.
서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기 관리해준다.

서블릿 객체는 싱글톤으로 관리되는데,
고객의 요청이 올 때 마다 계속 객체를 생성하는 것은 비효율적이다.
그래서 최초 로딩 시점에 서블릿 객체를 미리 만들어두고 재활용한다.
모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근하게 된다.
같은 인스턴스를 사용하기 때문에 공유 변수 사용 주의해야 한다.
서블릿 컨테이너 종료시 함께 종료된다.

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

멀티 쓰레드

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

문제는 멀티 쓰레드를 어떻게 관리할 것이냐 이다.
다중 요청이 들어올때마다 쓰레드를 생성하게 되면,

동시 요청을 처리할 수 있게되고, 리소스(CPU, 메모리)가 허용될 때 까지 처리가 가능하다.
또 하나의 쓰레드가 지연되어도, 나머지 쓰레드는 정상 동작하게 된다.

하지만 쓰레드 생성 비용이 굉장히 높고,
요청이 올때마다 쓰레드를 생성하게 되면 응답 속도가 느려지게 된다.
또 쓰레드 컨텍스트 스위칭 비용(CPU 코어에 관련..?)이 추가로 발생하게 된다.

그리고 쓰레드 생성에 제한을 두지 않으면 CPU 메모리가 임계점을 넘어 서버가 죽을 수도 있다.

쓰레드 풀

필요한 쓰레드를 쓰레드 풀에 보관하고 관리하는 것이다.
쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리한다. 톰캣은 최대 200개 기본 설정 (변경 가능)

쓰레드가 필요하면, 이미 생성되어 있는 쓰레드를 쓰레드 풀에서 꺼내서 사용한다.
사용을 종료하면 쓰레드 풀에 해당 쓰레드를 반납한다.
최대 쓰레드가 모두 사용중이어서 쓰레드 풀에 쓰레드가 없으면?
기다리는 요청은 거절하거나 특정 숫자만큼만 대기하도록 설정할 수 있다.

이러한 방식은 쓰레드가 미리 생성되어 있으므로, 쓰레드를 생성하고 종료하는 비용(CPU)이 절약되고, 응답 시간이 빠르다.
생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있다.

WAS의 주요 튜닝 포인트는 최대 쓰레드(max thread) 수이다.

이 값을 너무 낮게 설정하면?
동시 요청이 많으면, 서버 리소스는 여유롭지만, 클라이언트는 금방 응답 지연된다.

이 값을 너무 높게 설정하면?
동시 요청이 많으면, CPU, 메모리 리소스 임계점 초과로 서버 다운

장애 발생시?
클라우드면 일단 서버부터 늘리고, 이후에 튜닝 클라우드가 아니면 열심히 튜닝

하지만 적정 숫자는
애플리케이션 로직의 복잡도, CPU, 메모리, IO 리소스 상황에 따라 모두 다르기 때문에 성능 테스트가 답이다.

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

HTML, HTTP API, CSR, SSR

데이터를 제공할 때, 여라깆 방식으로 제공하게 된다.

정적 리소스의 경우,
고정된 HTML 파일, CSS, JS, 이미지, 영상 등을 그냥 제공하면 된다.

HTML 페이지의 경우
동적으로 필요한 HTML 파일을 생성해서 전달한다.

HTTP API를 통해 제공하게 될 경우
HTML이 아닌 데이터를 전달하게 되는데 주로 JSON 형식을 사용한다.
다양한 시스템에서 호출하게 된다.

백엔드 개발자는 이 세가지 경우를 어떻게 제공할 것인지 고민해야 한다.

SSR - 서버 사이드 렌더링

서버에서 최종 HTML을 생성해서 클라이언트에 전달한다.
주로 정적인 화면에서 사용한다.
관련기술 : JSP, 타임리프 -> 백엔드

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

HTML 결과를 자바스크립트를 사용해 웹 브라우저에서 동적으로 생성해서 적용
주로 동적인 화면에 사용, 웹 환경을 마치 앱 처럼 필요한 부분부분 변경할 수 있다.
예) 구글 지도, Gmail, 구글 캘린더
관련기술: React, Vue.js -> 웹 프론트엔드 개발자

백엔드 개발자 입장에서 UI 기술

백엔드 개발자는 서버 사이드 렌더링 기술 학습 필수 (JSP, 타임리프)
화면이 정적이고, 복잡하지 않을 때 사용

웹 프론트엔드 - 클라이언트 사이드 렌더링 기술 (React, Vue.js)
복잡하고 동적인 UI 사용
웹 프론트엔드 개발자의 전문 분야

선택과 집중
백엔드 개발자의 웹 프론트엔드 기술 학습은 옵션

profile
I am me

0개의 댓글