[스프링 & Java] 서버 vs 클라이언트, 웹 서버 vs WAS

Gamchan Kang·2023년 10월 9일
0

백엔드

목록 보기
1/5

* 이 포스팅은 부산대학교 2023 백엔드 미니 부트캠프 2주차 학습 내용을 정리한 글입니다.

HTTP 프로토콜 개요

데이터의 송수신이 이뤄지기 위해서는 단말기 즉, 클라이언트와 서버 간 요청(request)-응답(response)이 있어야 한다. GET은 클라이언트가 서버에 데이터를 요청/읽는 행위이고 POST는 클라이언트가 서버에 데이터를 전송/쓰는 행위이다.

데이터가 전송될 때 HTTP 프로토콜은 stream 형태로 데이터를 송/수신하는데 이때 stream이란 시작과 끝을 알 수 없는 데이터 흐름을 이야기한다. 그렇다면 어떤 데이터를 송/수신하고 어떻게 읽는지에 대한 정보 또한 필요하다.

따라서 데이터를 송수신할 때 데이터의 메타 정보를 header에 포함한다. 흔히 접하는 URL(Uniform Resource Location)도 이런 메타 정보에 해당한다.

header 정보 중 가장 중요한 데이터는 2가지이다. 하나는 Status-Code, 하나는 Content-Type이다.

Status-Code

Status-Code는 클라이언트 요청에 따라 서버가 어떻게 동작했는지 나타내는 코드이다. 100번대 부터 500번대 까지 있는데, 각 다음과 같다.

Status-Code설명
100번대대기 상태
200번대성공
300번대리다이렉션
400번대클라이언트 오류
500번대서버 오류

Content-Type

HTTP 헤더의 Content-Type 필드는 송수신되는 데이터의 종류를 나타낸다. 기본 값은 text/html인데 아무 것도 설정하지 않으면 html 형식으로 데이터가 송수신된다. 크롬의 개발자 도구에서도 똑같이 기본 Content-Type이 text/html로 되어있으며, 이 때 Content-Type 필드를 표시하지 않는다.

이렇게 type/subtype 순으로 데이터 종류를 나타내는 포맷을 MINE(Multipurpose Internet Mail Extension)이라고 한다. 처음 MINE은 이메일 시스템에서 고안되었다고 한다. 흔히 사용되는 JSON 타입 데이터는 Content-Type 필드에 'application/json' 값을 설정하면 해당 데이터가 JSON 형식으로 송수신된다.

서버에서 요청 정보

서버의 부하를 최소한으로 하기 위해서 요청/응답 과정이 끝나면 서버에서 요청 정보가 사라진다. 이는 HTTP 프로토콜의 state-less 정책이라고 한다. 추후에 언급되지만, 이렇게 요청 정보의 수명이 짧기 때문에 이를 저장할 세션이라는 메모리 공간을 따로 할당하기도 한다.

웹 서버와 WAS

그렇다면 Status-Code와 Content-Type으로 알맞게 파싱된 데이터는 어떻게 다뤄질까? 정확한 동작을 위해 서버 측 동작 구조를 살펴볼 필요가 있다.

서버의 구성

기기로서의 서버 vs 소프트웨어로서의 서버

흔히 서버라고 하는 것은 물리적인 것과 논리/가상적인 것으로 나눌 수 있다. 실제로 기기로서 서버는 컴퓨팅 역할을 하는 기기이다. 데이터는 결국 실제 메모리에 저장되어 있기 때문에 마치 '1번 서랍 속 문서'를 꺼내달라는 것과 같다.

가상화된 서버 즉, 프로그램으로서의 서버는 클라이언트 측에서 요청받은 내용을 바탕으로 저장소에서 데이터를 가져오는 프로그램이다. 더 와닿게 설명하자면, 기기로서의 서버는 실제 CPU와 하드디스크로 이뤄진 컴퓨터이고 프로그램으로서의 서버는 그 위에 돌아가는 윈도우 같은 운영체제와 같다.

이때 클라이언트의 요청을 효율적으로 처리하기 위해 소프트웨어로 구현되는 서버는 크게 웹서버와 웹 어플리케이션 서버(WAS)로 구성된다.

  • 웹 서버는 HTML, CSS, 이미지와 같은 정적인 컨텐츠를 클라이언트에게 전송한다.
  • WAS는 동적인 컨텐츠 전송과 보안, DB와의 상호 작용 등 다소 복잡한 연산을 수행한다.

웹 서버와 WAS를 구분하는 이유

성능 최적화

  • 정적/동적 컨텐츠 처리의 분리로 DB와 상호 작용의 유무에 따라 클라이언트에게 적절한 추가 처리로 전송한다.
  • 웹 서버가 WAS 인스턴스 간 트래픽을 분산해(로드 밸런싱) 시스템 확장성과 서비스 안정성을 확보한다.
  • 자주 접근하는 컨텐츠를 따로 캐싱하여 성능을 향상한다.

서버 리소스

  • 각각 리소스를 독립적으로 할당하고 관리하여 유연하게 관리할 수 있다.
  • 특히 WAS에서 스레드를 관리하면서 생성, 소멸에서 오버헤드를 줄일 수 있다.

유지보수 & 확장성

  • 웹 서버와 WAS를 따로 관리하고 확장하여 필요한 부분만 유지보수 혹은 확장할 수 있다.
  • 수직적/수평적 스케일링에 용이해 자체 성능 향상 및 효율적인 트래픽 분산이 가능하다.

보안

  • 실제 데이터 베이스와 클라이언트 간의 단계를 세분화하면서 데이터에 직접적인 접근을 막을 수 있다.
  • 요청 필터링, 유효성 검사를 통해서 SQL 인젝션, XSS 등을 막을 수 있다.
  • 웹 서버에서 접근 제어를 수행해서 리소스에 대한 접근을 컨트롤할 수 있다.

스프링에서의 WAS 동작

서블릿과 요청/응답

브라우저에서 특정 요청이 Stream으로 들어오면 웹 서버에 String으로 파싱되고 pre-processing이 이루어진다. 그리고 웹 서버는 WAS에 클라이언트 요청을 위임하여 좀 더 복잡한 연산이 이루어진다.

이때 웹 서버는 Apache를 많이 사용하고 Java 기반 WAS인 Tomcat을 주로 사용할 예정이다. 앞으로는 톰캣을 WAS 대용으로 언급하겠다.

톰켓에서 헤더와 바디로 파싱된 데이터는 request, response 객체로 rebuild 된다. 이는 서블릿 엔진에 전달되어 서블릿이라는 객체로 다시 만들어진다. request 객체는 기본적으로 모든 처리가 끝나고 response가 전송되었을 때 사라진다.

템플릿 엔진

HTTP 프로토콜의 기본 데이터 형식은 html이다. 이때 자바에서 동적 데이터 응답을 위해서는 2가지 방법을 생각할 수 있다.

  • 자바 코드 속 html 코드
  • html 코드 속 자바 코드

아무래도 후자가 더욱 간편해서 jsp, mustache 등으로 객체를 불러온 다음 html 코드 속을 넣도록 한다. 스프링부트에서 jsp를 뷰로 사용한다면 기본적으로 src/main/webapp/WEB-INF/ 내부에서 호출된다. mustache의 경우 프로젝트 루트 디렉토리 혹은 src/main/resourses 디렉토리 내부 application.yml 파일에 다음 내용을 추가한다.

spring:
  mustache:
    prefix: src/main/webapp/WEB-INF/
    suffix: .mustache

템플릿 엔진은 프로그래머가 동적 컨텐츠를 보다 쉽게 포함하도록 뷰 파일을 만들고 이를 서블릿 객체로 변환하여 응답하도록 하는 어플리케이션이다.

세션

요청/응답이 완료되더라도 특정 데이터를 저장하고 싶은 경우가 있을 수도 있다. 예를 들어 로그인 정보는 사용자가 로그아웃 요청을 하거나, 브라우저를 종료할 때까지 유지하고 싶은 정보 중 하나이다. 로그인 정보도 POST 동작으로 이루어지기 때문에, 서버가 클라이언트 로그인 정보를 유지하려면 서버의 특정 메모리 공간에 해당 데이터를 할당해야 한다.

세션은 서버 메모리의 힙 영역에 할당되는 객체로, 특정 요청/응답 이후에도 데이터를 유지하고 싶을 때 사용하는 객체이다. 흔히 세션을 보안과 관련지어 설명하는 데, 서버 메모리에 동적 할당으로 세션이 생성되기 때문이다. 메모리 해제로 세션이 사라진다면 세션 내부 데이터도 사라지기 때문에 로그인 정보와 같은 민감한 데이터를 세션에 저장한다.

그렇다면 세션은 언제 메모리에서 해제될까? 크게 4가지로 나눌 수 있다.

  1. 세션 타임아웃

설정된 유효 기간이 지나면 자동으로 만료된다. 사용자로부터 활동이 없는 경우 일정 시간 이후 세션이 메모리에서 해제된다.

  1. 사용자 로그아웃

로그아웃 처리 로직에서 세션을 명시적으로 무효화하거나 삭제하여 메모리 해제한다.

  1. 서버 설정

서버 로직에 따라 세션 데이터를 해제할 수 있다. 예를 들어, 메모리 사용량이 특정 임계값을 넘는다면 오래된 세션 데이터를 해제하는 로직을 만들 수 있다.

  1. 서버 재시작

서버가 재시작되면 메모리 초기화가 이루어져 세션 데이터가 해제된다.

기본적으로 세션은 브라우저가 종료되면서 해제된다. 로그인 정보 기억 기능은 서버 측 메모리인 세션이 아닌 클라이언트 측 메모리인 쿠키와 로컬 스토리지를 이용하여 구현된다. 세션, 쿠키는 메모리 할당 객체라는 공통점이 있지만, 세션은 서버 측 쿠키는 클라이언트 측 객체이다.

profile
Someday, the dream will come true

0개의 댓글