관리 메뉴

나구리의 개발공부기록

웹 애플리케이션 이해, 웹서버와 웹애플리케이션 서버, 서블릿, 동시 요청 - 멀티 쓰레드, HTML/HTTP API/CSR/SSR, 자바 백엔드 웹 기술 역사 본문

인프런 - 스프링 완전정복 코스 로드맵/스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

웹 애플리케이션 이해, 웹서버와 웹애플리케이션 서버, 서블릿, 동시 요청 - 멀티 쓰레드, HTML/HTTP API/CSR/SSR, 자바 백엔드 웹 기술 역사

소소한나구리 2024. 2. 8. 15:55

  출처 : 인프런 - 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (유료) / 김영한님  
  유료 강의이므로 정리에 초점을 두고 코드는 일부만 인용  

https://inf.run/Gmptq


1. 웹서버와 웹애플리케이션 서버

1) 웹 - HTTP 기반

  • 웹은 모두 HTTP 기반으로 동작
  • HTTP 메시지에 모든 것을 전송
  • 서버간의 데이터 전송, HTML, TEXT, IMAGE, JSON 등등 거의 모든 형태의 데이터 전송 가능

(1) 웹 서버(Web Server)

  • HTTP 기반으로 동작
  • 정적 리소스를 제공, 기타 부가기능 제공
  • 정적리소스 : 특정 디렉토리에 정적(파일)HTML, CSS, JS, 이미지, 영상 등의 데이터가 있을 때 클라이언트가 요청을 하면 서버가 파일을 HTTP 프로토콜로 데이터를 전송함 (특별히 하는 것이 없음)
  • 예) NGINX, APACHE

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

  • HTTP 기반으로 동작
  • 웹 서버 기능 포함(정적 리소스 제공) + 프로그램 코드를 실행해서 애플리케이션 로직(동적 HTML, HTTP API(JSON), 서블릿, JSP, 스프링 MVC 등)을 수행
  • 예) 톰캣(Tomcat), Jetty, Undertow

(3) 웹 서버와 웹 애플리케이션 서버의 차이

  • 웹 서버는 정적 리소스(파일) 제공, WAS는 애플리케이션 로직을 이용
  • 웹 서버도 프로그램을 실행하는 기능을 포함하기도 하고, 웹 애플리케이션 서버도 웹서버의 기능을 제공하기 때문에 사실 둘의 용어도 경계도 모호한 면이 있음
  • 자바는 서블릿 컨테이너 기능을 제공하면 WAS이긴 하지만 서블릿 없이 자바코드를 실행하는 서버 프레임워크도 있어서 애매하긴 함
  • 간단히 WAS는 애플리케이션 코드를 실행하는데 더 특화가 되어있다 정도로 인지하면 됨

(4) 웹 시스템 구성 - WAS, DB

  • WAS는 정적 리소스, 애플리케이션 로직 모두 제공 가능하므로 WAS, DB 만으로 시스템 구성이 가능함
  • 하지만 WAS가 너무 많은 역할을 담당하여 서버 과부하가 발생할 우려가 많음
  • 가장 비싼 비용이 발생하는 애플리케이션 로직이(데이터베이스를 조회하고, 다른 서버를 연결하는 등 여러 비즈니스 로직이 들어감) 정적 리소스 때문에 수행이 어려울 수 있음
  • WAS는 코드오류 등으로 인해 장애가 날 확률이 높은데 장애 발생시 오류가 났다는 안내 페이지 조차 노출이 불가능
  • 작은 시스템은 이렇게 구축해도 되지만 큰시스템에서는 이렇게 구축하면 안됨
  • 단, 화면을 제공하는 것이아니라 API 등으로 데이터만 주고 받고 할 때에는 WAS 서버만 구축해도 됨

WAS, DB만으로 웹 시스템을 구성

(5) 웹 시스템 구성 - WEB, WAS, DB

  • 정적 리소스는 웹 서버가 처리하고 애플리케이션 로직같은 동적인 처리가 필요하면 웹 서버가 WAS에 요청을 위임하여 애플리케이션 로직을 전담
  • 정적 리소스가 많이 사용되면 웹 서버를 증설하고, 애플리케이션 리소스가 많이 사용되면 WAS를 증설하는 방식으로 효율적인 리소스가 가능해짐(실제로는 더 복잡함)
  • 정적 리소스만 제공하는 웹서버는 잘 죽지 않으므로 WAS나 DB가 장애가 발생했을 때 오류 화면을 뿌리도록 설정할 수 있음(고객에게 노출)
  • 해당 웹 시스템을 기반으로 점점 발전하여 구성하고 있음

WEB, WAS, DB로 웹 시스템을 구성


2. 서블릿(Servlet)

1) 서블릿

(1) HTML Form 데이터 전송(POST - 저장)

  • HTML Form(POST)으로 데이터를 만들어서 전송하면 웹 브라우저가 HTTP 메시지를 정해진 형식으로 생성하여 서버로 전송
  • HTML Form으로 전송시 기본 형식 타입 : Content-Type : application/x-www-form-urlencoded (디폴트)

 

(2) 웹 애플리케이션 서버를 직접 구현(원초적인 방법) VS 서블릿을 지원하는 WAS사용

  • 만약 직접 WAS를 직접 구현해야 하면 소켓 연결, 요청 메시지 파싱, 비즈니스 로직 실행, 응답 메시지 생성 등의 세세한 로직을 모두 직접 구현해야함
  • 하지만 서블릿을 지원하는 WAS를 사용하게되면 의미있는 비즈니스 로직(초록 박스)만 직접 구현하면 되고 나머지는 서블릿이 알아서 해줌(자동화)

좌) 직접 구현 / 중) 서블릿을 지원하는 WAS를 사용했을 때 / 우) 생성 된 응답 메세지 예시

(3) 서블릿의 특징

  • 서블릿의 기본 구조
  • urlPatterns(/hello)의 URL이 호출되면(예 - localhost:8080/hello) 서블릿 코드가 실행 됨
  • HTTP 요청 정보를 편리하게 사용할 수 있는 HttpServletRequest와 HTTP 응답 정보를 편리하게 제공할 수 있는 HttpServletResponse 객체가 제공 되어 HTTP스펙을 매우 편리하게 사용이 가능함
@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) {
    // 애플리케이션 로직
    }
}

 

(4) 서블릿 - HTTP요청, 응답 흐름

  • HTTP요청이 오면 WAS는 Request, Response 객체를 새로 만들어서 서블릿 객체를 호출함
  • 개발자는 Request 객체에서 HTTP요청 정보를 편리하게 꺼내서 사용할 수 있고, Response 객체에 HTTP응답 정보를 편리하게 입력 할 수 있음
  • WAS는 Response객체에 담겨있는 내용으로 HTTP응답 정보를 생성하여 웹 브라우저에 전송

좌) 서블릿 WAS의 요청 응답 흐름 / 우) 서블릿 컨테이너가 싱글톤으로 관리

 

(5) 서블릿 컨테이너

  • 톰캣처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 함
  • 서블릿 컨테이너는 서블릿 객체를 생성, 초기화 호출, 종료하는 생명주기를 다 관리 해줌
  • 서블릿 객체는 싱글톤으로 관리됨
  • 고객의 요청이 올 때 마다 서블릿 객체를 생성하는 것이 아니라 최초 로딩 시점에 서블릿 객체를 만들어두고 재사용
  • 모든 요청은(같은 서버에 요청이 왔을 때) 동일한 서블릿 객체 인스턴스에 접근하고 서블릿 컨테이너 종료 시 함께 종료 됨
  • 싱글톤은 공유 변수 사용에 주의해야함
  • JSP도 서블릿으로 변환 되어서 사용
  • 동시 요청을 위한 멀티 쓰레드 처리를 지원

3. 동시 요청 - 멀티 쓰레드

서블릿 객체를 호출하는 것은 쓰레드

1) 쓰레드 - 서블릿 객체를 호출

(1) 쓰레드

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

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

  • 요청이 오면 쓰레드가 할당 되어 쓰레드가 애플리케이션을 호출함
  • 응답이 완료 되면 쓰레드는 휴식

단일 요청 - 단일 쓰레드

 

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

  • 요청1이 들어와서 쓰레드가 요청을 처리 중에 지연 되었다고 가정을 하고 요청2가 추가로 연결이 되면 쓰레드가 사용 중이므로 계속 대기상태에 빠지고 요청1, 요청2가 모두 죽음

다중 요청 - 단일 쓰레드

 

(4-1) 요청 마다 쓰레드 생성

  • 각 요청마다 신규 쓰레드를 생성 하여 요청1을 처리하는 쓰레드가 지연되어도 요청2는 새로 생성된 쓰레드가 servlet을 호출하여 응답 처리 할 수 있음

(4-2) 요청 마다 쓰레드 생성 - 장점

  • 리소스(CPU, 메모리)가 허용할 때까지 동시 요청을 처리할 수 있음
  • 하나의 쓰레드가 지연되어도 나머지 쓰레드가 정상 동작 함

(4-3) 요청 마다 쓰레드 생성 - 단점

  • 쓰레드는 생성 비용은 매우 비싸기때문에(리소스가 많이 소모됨) 고객의 요청이 올 때 마다 쓰레드를 생성하면 응답 속도가 늦어짐
  • 멀티 쓰레드는 컨텍스트 스위칭 비용이 발생
  • 컨텍스트 스위칭: 쓰레드를 처리하는 코어(코어는 쓰레드를 동시에 수행할 수 없음)가 쓰레드를 번갈아면서 처리할 때(쓰레드의 전환)걸리는 시간
  • 쓰레드 생성에 제한이 없으면 고객 요청이 너무 많이 왔을 때 CPU와 메모리의 임계점이 넘어가서 서버가 죽을 수 있음

요청 마다 쓰레드를 생성

 

(5-1) 쓰레드 풀 - 요청마다 쓰레드 생성의 단점을 보완

  • 필요한 쓰레드를 쓰레드 풀에 보관하고 관리
  • 쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리
  • 톰캣은 최대 200개 기본 설정(변경 가능 - 검색)

(5-2) 사용

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

(5-3) 장점

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

 

(5-4) 실무 팁(성능튜닝 - 백엔드 개발자에게 중요한 기본기)

  • WAS의 주요 튜닝 포인트는 최대 쓰레드 수(max thread)
  • 최대 값을 너무 낮게 설정하게 되면 동시 요청이 많아졌을 때 서버 리소스는 여유롭지만 클라이언트는 응답이 지연 됨
  • 이런 설정이 잘못된 것을 모르고 무분별하게 클라우드를 추가로 결제하여 서버를 증설하면 백엔드 개발자로서 부끄러운 일
  • 적어도 CPU의 사용률이 50%는 되어야 함

너무 적은 CPU 사용률

  • 최대 값을 너무 높게 설정 하면 동시 요청이 많아졌을 때 CPU, 메모리 리소스 임계점 초과로 서버가 다운 됨
  • 장애가 발생했을 때 클라우드를 사용 중이라면 서버부터 늘리고 이후에 튜닝(임시로 조치 후 튜닝)하고 자체 서버라면 서버가 절대 죽지 않도록 평소에 열심히 튜닝해야함..

(5-5) 쓰레드 풀의 적정 숫자

  • 애플리케이션 로직의 복잡도, CPU, 메모리 IO리소스 상황에 따라 모두 다를 수밖에 없음
  • 대략적으로 감을 잡는 것이지 최적의 값을 찾을 수 없으므로 성능 테스트를 최대한 실제 서비스와 유사하게 해야 함
  • 툴: 아파치 ab, 제이미터, nGrinder

(5-6) WAS의 멀티 쓰레드 지원 핵심

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

4. HTML, HTTP API, CSR, SSR

(1) 정적 리소스

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

(2) 동적인 HTML 페이지

  • WAS가 DB에서 필요한 정보를 조회하고 동적으로 필요한 HTML파일을 생성해서 전달하면 웹브라우저는 HTML을 해석하여 출력함

(3-1) HTTP API

  • HTML이 아닌 데이터를 전달(JSON, XML)
  • 데이터만 주고 받으며 UI 화면이 필요하면 클라이언트가 별도 처리
  • 다양한 시스템에서 호출

(3-2) HTTP API - 다양한 시스템에서 호출(연동)

  • 주로 JSON 형태로 데이터 통신
  • UI클라이언트 접점
    • 앱 클라이언트(아이폰, 안드로이드, PC앱)
    • 웹 브라우저에서 자바스크립트를 통한 HTTP API호출
    • React, Vue.js 같은 웹 클라이언트
  • 서버 to 서버
    • 주문서버 -> 결제 서버
    • 기업간 데이터 통신 등

다양한 시스템(웹,앱 클라이언트나 서버 to 서버 간의 통신)에서의 호출이 가능

 

(4) 서버사이드 렌더링(SSR)

  • HTML 최종 결과를 서버에서 만들어서 웹 브라우저에 전달
  • 주로 정적인 화면에 사용
  • 관련기술: JSP, 타임리프 등
  • 백엔드 개발자 필수, 3~4일 공부 후 바로 현업 프로젝트를 들어갈 수 있음

SSR

(5) 클라이언트 사이드 렌더링(CSR)

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

CSR

** 참고

  • React, Vue.js를  CSR + SSR 동시에 지원하는 웹 프레임워크도 있음
  • SSR을 사용하더라도 자바스크립트를 사용해서 일부를 동적으로 변경 가능

(6) 백엔드 개발자 입장에서의 UI 기술

  • 백엔드 - 서버 사이드 렌더링 기술
    • JSP, 타임리프
    • 화면이 정적이고 복잡하지 않을 때 사용
    • 백엔드 개발자는 서버 사이드 렌더링 기술 학습 필수
  • 웹 프론트엔드 - 클라이언트 사이드 렌더링 기술
    • React, Vue.js
    • 복잡하고 동적인 UI 사용
    • 웹 프론트엔드 개발자의 전문분야
  • 선택과 집중
    • 백엔드 개발자의 웹 프론트엔드 기술학습은 옵션
    • 백엔드 개발자는 서버, DB, 인프라 등등 수많은 백엔드 기술을 공부해야함
    • 웹 프론트엔드도 깊이있게 잘 하려면 오랜 시간이 필요함

5. 자바 백엔드 웹 기술 역사

1) 과거 기술

  • 서블릿(1997) : 자바코드로 짜다보니 동적인 HTML 생성이 어려움
  • JSP(1999) : HTML 생성은 편리하지만, 비즈니스 로직까지 너무 많은 역할을 담당하게 됨
  • 서블릿, JSP 조합 MVC 패턴 사용 : 모델, 뷰, 컨트롤러로 역할을 나누어 개발
  • MVC 프레임워크 춘추 전국 시대(2000초 ~ 2010초) : MVC 패턴 자동화 복잡한 웹 기술을 편리하게 사용할 수 있는 다양한 기능 지원 (스트럿츠, 웹워크, 과거버전의 스프링 MVC 등)

2) 현재 사용 기술

(1) 애노테이션 기반의 스프링 MVC 등장

  • @Controller
  • 스프링 MVC 프레임워크로 통일이 됨

(2) 스프링 부트의 등장(개발자들이 불편해 했었던 기능들을 자동으로 제공)

  • 스프링 부트는 서버를 내장 (과거에는 서버에 WAS를 직접 설치하고 소스는 WAR파일을 만들어서 설치한 WAS에 배포했었음)
  • 스프링 부트는 빌드 결과(JAR)에 WAS 서버가 포함되어있어 빌드 배포가 단순화됨

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

(1) Web Servlet - Spring MVC

  • 스프링 MVC는 서블릿 기반으로 동작
  • 멀티쓰레드 등의 장점이 있음

(2) Web Reactive - Spring WebFlux(스프링 웹 플럭스)의 특징 및 단점

  • 비동기 넌 블러킹 처리
  • 최소 쓰레드 최대 성능 - 쓰레드 컨텍스트 스위칭 비용 효율화
  • 함수형 스타일로 개발 - 동시처리 코드 효율화
  • 서블릿 기술을 사용하지 않음
  • 웹 플럭스는 기술적 난이도가 매우 높고 RDB 지원이 아직은 부족함
  • 일반 MVC의 쓰레드 모델도 충분히 빠름
  • 실무에서 아직 많이 사용하지는 않음

(4) 자바 뷰 템플릿 역사 - HTML을 편리하게 생성하는 뷰 기능

  • JSP : 속도 느림, 기능 부족
  • 프리마커(Freemarker), 벨로시티(Velocity) : 속도 문제 해결, 다양한 기능 지원
  • 타임리프(Thymeleaf)
    • 내추럴 템플릿: HTML의 모양을 유지하면서 뷰 템플릿 적용이 가능
    • 스프링 MVC와 강력한 기능 통합
    • 성능은 프리마커와 벨로시티가 더 빠르지만 웬만한 사이트는 이슈가 되지 않아서 타임리프를 선택하는 것을 권장함