HTTP의 Stateless, 비연결성

    모든 것이 HTTP


    • HTTP는 HyperText Transfer Protocol의 약자다. 
    • 현재는 HTTP 메시지에 모든 것을 담아서 전송한다. (HTML, TEXT, 이미지, 음성, 영상, 파일, JSON, XML)
    • 거의 모든 형태의 데이터가 전송 가능.
    • 서버 간에 데이터를 주고 받을 때도 대부분 HTTP를 사용한다. 

     

    기반 프로토콜은 뭘까?


    • TCP : HTTP/ 1.1 , HTTP/ 2는 TCP 위에서 동작함
    • UDP : HTTP / 3 

    크롬에서 F12를 누르면, 프로토콜에서 현재 어떤 HTTP로 내가 파일을 사용하고 있는지를 볼 수 있다. 

    현재 HTTP/1.1을 주로 사용하고 있으며, HTTP/2, HTTP/3도 사용 빈도가 증가하고 있다. TCP는 안정적인 프로토콜이지만, 3 Way HandShake를 해야하며 포함되는 데이터가 많기 때문에 느린 편이다. UDP 프로토콜에서 어플리케이션 기반으로 성능을 최적화해서 사용하도록 한 것이 HTTP3다. 

     

    HTTP의 특징


    • 클라이언트 서버 구조
    • Request Response 구조
    • 클라이언트는 서버에 요청을 보내고, 응답을 기다린다.
    • 서버가 요청에 대한 결과를 만들어서 응답함. 

    HTTP는 클라이언트가 HTTP 메세지를 통해서 서버에 요청을 보낸다. 그리고 클라이언트는 서버에서 응답이 올 때 까지 대기를 한다. 서버가 요청에 대한 결과를 만들어서 응답을 주면, 클라이언트가 그 응답 결과를 열어서 동작하는 방식이다.

    위의 내용은 표면적인 내용이다. 사실은 클라이언트, 서버를 분리해서 봐야한다. 

    • 서버는 비즈니스 로직에만 집중한다.
    • 클라이언트는 UI, 사용성에만 집중한다.

    이렇게 분리해서 보게 되면 클라이언트, 서버는 독립적으로 진화할 수 있게 된다. 예를 들어 트래픽이 어마어마하게 늘어나면, 백엔드 기술을 어떻게 고도화해서 트래픽을 소화할 수 있는지만 고민을 하면 된다. 클라이언트는 이런 작업들을 몰라도 된다. 

     

    HTTP의 중요한 특징 : 무상태 프로토콜(Stateless)

    무상태 프로토콜은 서버가 클라이언트의 상태를 보존하지 않는다는 것이다. 

    • 장점 : 서버 확장성 높음 (스케일 아웃)
    • 단점 : 클라이언트가 추가 데이터 전송

    서버가 클라이언트의 상태를 보존하지 않는다. HTTP는 무상태 프로토콜을 지향하는 것이 좋다. 아래는 무상태와 상태 유지를 비교한 예시이다. 

     

     Stateful : 상태 유지

    • 첫번째 상황
      고객 : 이 노트북이 얼마인가요?
      점원 : 100만원입니다. (노트북 상태 유지)
    • 두번째 상황
      고객 : 2개 구매하겠습니다.
      점원 : 200만원입니다. 신용카드, 현금 중에 어떤 걸로 구매하시겠어요? (노트북, 2개 상태 유지)
    • 세번째 상황
      고객  : 신용카드로 구매하겠습니다.
      점원 : 200만원 결제 완료되었습니다. (노트북, 2개, 신용카드 상태 유지) 

     

    Stateful : 상태유지, 점원이 중간에 바뀐다. 

    • 첫번째 상황
      고객 : 이 노트북이 얼마인가요?
      점원A: 100만원입니다.
    • 두번째 상황
      고객 : 2개 구매하겠습니다.
      점원B : ? 무엇을 2개 구매하시겠어요?
    • 세번째 상황
      고객  : 신용카드로 구매하겠습니다.
      점원C : ?무슨 제품을 몇 개 신용카드로 구매하시겠어요?

    → 상태 유지를 하더라도, 다른 점원은 애초에 어떤 상태였는지 모른다. 따라서 다른 점원에게도 클라이언트의 상황을 계속 알려줘야한다.

     

    Stateless, 점원이 중간에 바뀌면? 

    • 첫번째 상황
      고객 : 이 노트북이 얼마인가요?
      점원A : 100만원입니다.
    • 두번째 상황
      고객 : 노트북 2개 구매하겠습니다
      점원B : 노트북 2개는 200만원입니다. 신용카드, 현금 중에 어떤 걸로 구매하시겠어요?
    • 세번째 상황
      고객 : 노트북 2개를 신용카드로 구매하겠습니다.
      점원C : 200만원 결제 완료되었습니다.

    → 고객에 대한 정보를 중간 중간에 다 하나씩 넘기기 때문에 중간에 점원이 바껴도 아무 문제가 없다. 

     

    Stateful, Stateless 차이 정리 

    Stateful(상태 유지)

    • 중간에 다른 점원으로 바뀌면 안된다. 만약에 다른 점원으로 바뀐다면, 클라이언트의 상태 정보를 다른 점원에게도 알려줘야한다. 
    • 그렇게 하고 싶지 않다면 서버 하나를 온전히 클라이언트에게 배정해줘야 한다.

    Stateless(무상태)

    • 클라이언트의 상태 정보를 계속 주기 때문에 다른 점원으로 바껴도 상관없다. 
    • 갑자기 고객이 증가해도 점원을 대거 투입할 수 있다.
      → 무상태는 응답 서버를 쉽게 바꿀 수 있다. 무한한 서버 증설이 가능함.

    상태유지는 특정 클라이언트를 특정 서버가 전담하는 식으로 대응된다. 예를 들어 요청을 처리하다가 서버 오류가 나면 처음부터 다시 해야한다. 그리고 동적으로 서버를 확장하기도 어렵다.

    무상태는 그 때마다 놀고 있는 서버를 호출해도 아무 문제가 없다. 왜냐하면 클라이언트가 서버를 호출할 때, 현재의 상태를 서버에게 다 넘겨주기 때문이다. 이 경우 요청을 처리하던 서버에 문제가 발생해도, 클라이언트가 다른 서버를 호출해서 처리가 가능하다. 

    이런 이유 때문에 무상태는 스케일 아웃(같은 기능을 하는 서버군들의 수평 확장)하는데 굉장히 유리하다. 예를 들어 이벤트를 할 때, 잠깐 서버를 많이 붙여버리는 방법도 있다. 

     

    Stateless의 한계


    모든 것을 무상태로 설계 할 수 없는 경우도 발생한다. 

    무상태 

    •  로그인이 필요없는 단순한 서비스 소개 화면 정도의 구현

    상태 유지

    •  로그인 : 
       로그인한 사용자의 경우 로그인 했다는 상태를 서버에 유지를 해줘야한다. 일반적으로는 브라우저 쿠키와 서버 세션등을 함께 조합하여 사용하면서 상태를 유지한다.

    어쩔 수 없이 해야하는 Stateful이 있다. 이런 상태 유지를 최소한으로만 사용하도록 하고, 최대한 Stateless하게 설계하는 것이 중요하다. 반면 Stateless는 클라이언트의 상태를 전달해야하기 때문에 Stateful보다는 요청할 때 전달하는 데이터가 많다. 

     

    비연결성


    TCP/IP 연결 유지 모델

    1. 클라이언트1 TCP/IP 소켓 연결한 다음 요청을 보내고 응답을 받는다.(연결 유지)
    2. 클라이언트2 TCP/IP 소켓 연결한 다음 요청을 보내고 응답을 받는다.(연결 유지)
    3. 클라이언트3 TCP/IP 소켓 연결한 다음 요청을 보내고 응답을 받는다.(연결 유지)

    서버 관점에서 보면 위처럼 계속 연결을 유지하는 것은 서버의 자원이 계속 소모되고 있는 것으로 이해할 수 있다. 정말로 통신을 하고 있는 상황이면 상관이 없을 수는 있으나, 클라이언트가 놀고 있을 때 연결이 유지된다면 자원이 소모되는 것으로 볼 수 있다. 

    TCP/IP 연결 유지X 모델

    연결을 유지하지 않는 모델은 요청이 오면 클라이언트와 서버를 연결하고, 응답이 오면 TCP/IP 연결을 종료하는 형태다. 

     

    비연결성 → 연결 유지X 모델


    • HTTP는 기본이 연결을 유지하지 않는 모델이다.
    • 일반적으로 초 단위의 이하의 빠른 속도로 응답을 한다. 그래서 1시간 동안 수천명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청은 수십개 이하로 매우 작음. 
      → 웹 브라우저에서 계속 연속해서 검색 버튼을 누르지는 않는다.

    즉, 필요할 때만 데이터를 연결을 해서 주고 받으면 서버 자원을 매우 효율적으로 사용할 수 있다.

     

    비연결성 → 연결 유지X 모델 한계 및 극복


    좌 : 연결 유지 모델 X / 우 : 지속 연결 모델

    • TCP/IP 연결을 새로 맺어야 함. 3 Way Handshake 시간 추가 필요함
    • 웹 브라우저로 사이트를 요청하면 HTML 뿐만 아니라 자바스크립트, css, 추가 이미지 등 수 많은 자원이 함께 다운로드 된다.

     

    비연결성 모델은 기본적으로 연결을 끊고 다시 해야한다. 검색을 하다가 다음 페이지로 넘어가면, TCP/IP 연결을 새로 맺어야하는데 3 Way Handshake 시간이 추가되게 되는 셈이다. 이 뿐만 아니라 이 과정에서 수많은 자원이 함께 다운로드가 되는데, 자원을 하나하나 받을 때 마다 연결을 끊고 맺어야 하니 아주 비효율적이다. 예를 들어 HTML 하나받고 보니, 자바스크립트가 필요해서 또 연결하고, 자바스크립트 받았더니 이미지가 필요해서 다시 연결하는 식으로 비효율적으로 동작한다. 

    이런 문제는 HTTP 지속 연결(Persisent Connections)로 문제를 해결한다. 먼저 연결을 해두고, 연결을 유지한다. 내부적인 로직으로 몇십 초 정도 연결이 유지되게 되는데 어지간하면 HTML 페이지 하나를 다 받을 때까지 연결이 유지가 된다고 한다. 이렇게 요청에 대한 응답을 다 받으면 연결이 종료가 되게 된다. 

     

    스테이스리스를 기억하자 (서버 개발자들이 어려워하는 업무)

    항상 무상태로 갈 수 있는 것은 이 상태로 설계를 해야한다.


    정말 같은 시간에 딱 맞추어 발생하는 대용량 트래픽(선착순 이벤트, 명절 KTX 예약, 학과 수업 등록 등)은 비연결성 이런 것이 필요없다. 왜냐하면 수만명이 정말로 동시에 접속이 필요하기 때문이다. 

     

    HTTP 메시지


    대부분의 Resource는 HTTP를 이용해서 보낼 수 있다. 이 때 어떻게 HTTP에 Resource를 저장해서 보내는지를 알아보자.

     

    HTTP 메세지의 종류

    • 요청 메세지
    • 응답 메세지

     

     

    HTTP 메세지 구조

    HTTP 메세지의 구조는 요청, 응답 모두 위와 같은 구조를 가진다. empty Line은 공백 라인인데 반드시 Enter가 한 칸 들어가야한다고 보면 된다. 만약에 Body에 데이터를 넣지 않아도 된다고 하면, 그냥 공백 넣고 끝내면 된다. 

     

    Start Line 정리

    요청 메세지일 때(Request-Line)

    • request-line = method SP(공백) request-target SP HTTP-Version CRLF(엔터)
    • method는 서버가 수행해야 할 동작을 알려줌(GET/POST/PUT/DELETE)
    • Target(요청 대상)은 보통 절대 경로(/)로 시작을 하고 쿼리가 합쳐져서 들어가기도 한다.
    • → /search?q=hello&hi=ko <- 
    • HTTP Version
    • HTTP/1.1, HTTP/2, HTTP/3을 넣으면 된다.

     

    응답 메세지 일 때(Status-Line)

    • status-line = HTTP-version SP status-code SP reason-phrase CRLF
    • 상태코드(200,300,400 등)는 요청에 대한 결과를 나타내준다.
    • reason-phrase는 사람이 상태 코드를 이해할 수 있는 글임.  (OK, created)

     

    HTTP Header

    • header-field = field-name":" OWS(띄워쓰기 허용) field-value OWS(띄워쓰기 허용)
    • field-name은 대소문자의 구분이 없다.
    • 예1 : HOST: www.google.com  
    • 예2 : Content-Type: text/html;charset=UTF-8 Content-Length: 3423

    헤더에는 HTTP 전송에 필요한 모든 부가정보가 들어가있음. Body에 직접적인 데이터가 들어있다면, 헤더에는 필요한 메타 정보가 전부 들어있다(바디 내용이 뭔지, 바디 크기, 압축, 인증 정보, 웹 브라우저 정보 등)

     

    HTTP Body

    • Body에는 실제로 전송할 데이터를 넣는다. (HTML 문서, 이미지, 영상, JSON 등)

     

    'CS > 네트워크' 카테고리의 다른 글

    HTTP 메서드 활용  (0) 2021.12.06
    HTTP 상태 코드 정리  (0) 2021.12.04
    HTTP 메서드 관련 정리  (0) 2021.12.04
    URI와 웹 브라우저 요청 흐름  (0) 2021.12.04
    인터넷 네트워크 구조 (IP, TCP, UDP, DNS, PORT)  (0) 2021.10.11

    댓글

    Designed by JB FACTORY