본문 바로가기
Back-end

[모든 개발자를 위한 HTTP 웹 기본 지식] 3. HTTP 기본

by kkkdh 2022. 12. 1.
728x90

모든 것이 HTTP

  • HTTP는 HyperText Transfer Protocol의 약자로 지금은 모든 것을 HTTP 메시지에 담아서 전송한다.
  • HTML, TEXT
  • IMAGE, 음성, 영상, 파일
  • JSON, XML (API)
  • 거의 모든 형태의 데이터 전송이 가능하다.
  • 서버 간 데이터 송수신에도 대부분 HTTP를 사용한다. (TCP만 직접 이용하는 경우는 거의 없다.)

 

HTTP의 역사

  • HTTP/0.9 1991년: GET 메서드만 지운, HTTP header X
  • HTTP/1.0 1996년: method, header 추가
  • HTTP/1.1 1997년: 가장 많이 사용 중, 우리에게 가장 중요한 버전이다. (대부분의 기능이 포함되었고, 이후 버전들은 성능 개선에 초점)
    • RFC2068 (1997) > RFC2616 (1999) > RFC7230~7235 (2014)
  • HTTP/2 2015년: 성능 개선
  • HTTP/3 진행 중: TCP대신 UDP를 사용하여 성능 개선을 목표로 한다.

비교적 최근에 개발된 HTTP 2.0, 3 버전의 경우 성능 개선에 초점을 맞췄기 때문에, 우리의 경우에는 1.1 버전에 맞춰 정리를 할 예정이다.

 

기반 프로토콜

  • TCP: HTTP/1.1, HTTP/2
  • UDP: HTTP/3
  • 현재는 HTTP/1.1을 주로 사용한다.
    • HTTP/2, HTTP/3의 사용도 증가 추세

일단 HTTP/1.1의 스펙을 잘 파악하면, 2나 3은 성능 개선이 이루어진 버전이기 때문에 이후에 잘 습득 가능하다.

 

HTTP의 특징

  • client-server 구조
  • stateless protocol이며, 비연결성
  • HTTP message
  • 단순하며 확장 가능하다.

Client-Server Architecture

  • request, response 구조
  • client는 server에 요청(request)을 보내고, 응답(response)을 대기한다.
  • server가 요청에 대한 결과를 만들어 응답한다.

client와 server를 개념적으로 분리하는 것은 각자 작업을 분담함으로써 양쪽이 독립적으로 진화할 수 있게 한다는데 있어서 굉장히 중요한 포인트이다.

server는 business logic, 복잡한 data를 다루는 것에만 집중하고, client는 server에서 받아온 데이터를 이용해 얼마나 사용성이 좋은 UI를 제공할지에 대해서만 집중할 수 있게 된다.

 

정리하면, HTTP는 client-server architecture을 따르는 protocol로 통신을 하는 상황에서 client와 server로 역할이 나뉜 상태에서 message를 주고받는 방식을 취한다.


무상태 프로토콜 (Stateless)을 지향

  • 서버가 클라이언트의 상태를 보존하지 않는다.
  • 장점: 서버의 확장성이 높아짐 (scale out)
  • 단점: 클라이언트가 추가 데이터를 전송해야

Stateful vs Stateless 차이점은?

stateless가 무엇인지 알기 위해서 stateful 개념과 비교해보자. 두 가지 개념을 각각 설명하면 다음과 같다.

stateful: 통신하는 client의 정보를 유지한 상태로 통신

stateless: 통신하는 client의 정보를 유지하지 않고 통신

 

client의 정보를 유지하느냐 하지 않느냐를 기준으로 stateful과 stateless를 나누는데, 강의에서는 이것을 매장에서 노트북을 구매하는 상황을 예로 들었다.

 

간단히 정리하면 stateful은 나의 구매 과정을 한 명의 점원이 이전 정보를 기억하면서 결제를 담당해주는 방식이라면, stateless는 제품 선택, 구매 개수 선택, 결제 등의 단계에서 매 번 새로운 점원(사전 정보를 모르는)과 결제 과정을 진행한다고 생각하면 좋을 것 같다.

 

HTTP는 둘 중에서 stateless 방식을 지향하고, 이로 인해서 이전에 통신한 정보는 기억하지 않은 채로 client와 server가 통신을 지속하게 된다.

 

겉으로 보이기에는 이전의 정보를 유지하며 통신하는 방식이 훨씬 좋아 보이지만, 이렇게 하기 위해서는 많은 어려움이 따르며, 또한 stateless 방식에 따라 얻을 수 있는 장점 또한 다음과 같이 존재한다.

stateful의 경우 통신하던 서버가 고장나는 경우 작업이 불가능하다.

stateless의 경우 상태 정보가 필요없기 때문에, 다른 서버로 대체가 충분히 가능

이러한 이유로 scale out, 수평 확장에 유리하다는 장점이 있다.

 

Stateless의 실무적 한계

  • 모든 것을 무상태로 설계할 수는 없을 수 있다.
  • 예를 들어 로그인이 필요 없는 단순 서비스는 무상태로 구현이 가능
  • 하지만, 로그인 같이 상태 유지가 필요한 경우가 있다.
  • 이를 위해 로그인 했다는 상태 정보를 서버에 유지하며
  • 브라우저 쿠키와 서버의 세션 등을 결합해 상태 유지에 사용
  • 상태 유지는 최소한으로만 사용해야

비연결성 (Connectionless)

일반적인 TCP/IP를 사용해 연결을 유지하는 모델을 생각해보자. 

연결을 유지하는 모델 같은 경우에는 위와 같이 자원을 주고받고도 계속해서 서버와 연결을 계속 유지하기 때문에, 자원의 낭비가 굉장히 심할 것이다. 

반면, 연결을 유지하지 않는 모델은 필요한 정보를 주고받는 즉시 연결을 해제하여, 자원을 절약하는 방식을 취하려는 방식으로 동작한다.

 

비 연결성

  • HTTP는 기본적으로 연결을 유지하지 않는 모델에 해당한다.
  • 일반적으로 초 단위 이하의 빠른 속도로 응답
  • 1시간 동안 수천명이 서비스를 사용한다 할지라도 사실상 실제 서버에서 동시에 처리하는 요청은 수십 개 이하로 매우 작다.
    • 예) 웹 브라우저에서 계속해서 검색 버튼을 누르지는 않기 때문이다.
  • 서버 자원을 매우 효율적으로 활용할 수 있게 된다.

 

비 연결성의 한계와 극복

  • TCP/IP 연결을 매 번 새로 맺어야 한다. - 3 way handshake에 따른 시간이 추가적으로 소모된다.
  • 웹 브라우저로 사이트를 요청할 시 HTML 뿐만 아니라 css, js, 추가 이미지 등의 부가 파일들이 같이 다운로드됨.
  • 지금은 HTTP 지속 연결 (Persistent Connections)로 이러한 문제를 해결함
  • 또한 HTTP 2, 3에서는 다양한 최적화 방식으로 이러한 성능 문제를 개선했다.

낭비 발생 > HTTP 지속 연결로 성능 개성

오른쪽 그림과 같은 방식으로 연결을 한 번의 요청에 따른 HTML, css, javascript 파일을 받아오는 동안에는 유지할 수 있도록 개선한 방식이 HTTP 지속 연결 방식이다.

 

Stateless를 기억하자! (서버 개발자들이 주로 어려워하는 업무)

  • 정말 같은 시간에 딱 맞춰 발생하는 대용량 트래픽 (주로 이벤트)
  • 이런 경우 어떻게든 머리를 쥐어 짜내서 stateless로 최대한 구현할 수 있어야 대용량 트래픽에 효율적인 대응이 가능하다.

HTTP message

기본적으로 HTTP 메시지는 request, response 상황에 따라 다르게 생겼다.

이렇게 조금 다르게 생겼습니다.

구조 틀을 살펴보면 다음 그림과 같다.

위 그림을 보면 start-line 부분과 header 부분이 조금 차이가 있는 것을 확인할 수 있다. 또 HTTP message에는 필수적으로 start-line, header와 message body를 구분하기 위해 공백 라인이 포함되어야 하며, HTTP 요청 메시지도 HTTP method에 따라서 message body를 포함할 수 있다. (위의 예제는 GET method에 따른 request이기 때문에 message body가 없다.)

 

공식 HTTP 스펙에는 다음과 같이 HTTP-message를 정의한다고 함.

HTTP-message = start-line
               *(header-field CRLF)
               CRLF
               [message-body]

 

Start-line (시작 라인)

  • start-line = request-line(request) / status-line(response)
  • request-line = method SP(공백) request-target SP HTTP-version CRLF(엔터)

 

  • HTTP method: GET
  • request 대상: /search?q=hello&hi=ko
  • HTTP version: 1.1 

HTTP method 종류 (request)

  • GET: 조회
  • POST: 요청한 내역 처리
  • PUT: 수정
  • DELTE: 삭제
  • ...

HTTP method는 서버가 수행해야 할 동작을 지정하기 위해 사용한다.

 

요청 대상 (request)

absolute-path[?query] (절대 경로[?쿼리]의 형식을 따른다.)

절대경로 = "/"로 시작하는 경로를 의미한다.

 

Reponse message 상황일 때 start-line (response)

  • start-line = request-line / status-line
  • status-line = HTTP-version SP status-code SP reason-phrase CRLF(엔터)

 

  • HTTP 버전
  • HTTP 상태 코드: 요청 성공 혹은 실패 등의 정보를 나타낸다.
    • 200: 성공
    • 400: client request error
    • 500: server error
    • ...
  • 이유 문구(reason-phrase): 사람이 이해 가능한 짧은 상태 코드 설명 글

HTTP header

  • header-field = field-name":"OWS field-value OWS (OWS는 띄어쓰기 허용을 의미)
  • field-name은 대소문자 구별 x, 당연히 field-value는 대소문자 구별 O

request는 host의 domain name을 작성하고, response는 field-name과 field-value 쌍의 목록이 작성된다.

 

HTTP 헤더 사용 목적

  • HTTP 전송에 필요한 모든 부가 정보를 담는다.
  • 예) message-body 내용, 크기, 압축 정보, 인증 등....
  • 표준 헤더는 너무 많아 이후에 정리
  • 필요한 경우 임의의 헤더를 추가 가능 (물론 약속된 client와만 주고받을 수 있을 듯)

HTTP message body

 

response에서의 message-body

실제 전송할 데이터를 담는다.

ex) HTML document, image, video, json 등.. byte로 표현 가능한 모든 데이터를 전송하기 위해 사용한다.

 

HTTP는 단순하고 확장 가능하다는 장점이 있으며, 아마 이러한 이유로 크게 성공한 것이 아닐까라고 한다. 대부분의 크게 성공하는 표준 기술들은 단순하지만, 확장 가능한 기술들이라는 특징을 갖고 있다.

728x90

댓글