본문 바로가기
FrontEnd/HTTP

[HTTP] HTTP 기본

by 개발 Blog 2024. 10. 6.

공부 내용을 정리하고 앞으로의 학습에 이해를 돕기 위해 작성합니다.

 

모든 것이 HTTP

HTTP란?

HTTP(HyperText Transfer Protocol)는 클라이언트와 서버 간에 정보를 주고받기 위한 가장 기본적인 프로토콜이다. 거의 모든 데이터가 HTTP를 통해 전송되며, 웹뿐만 아니라 다양한 서비스에서 HTTP를 활용한다.

 

HTTP로 전송되는 것들

HTTP 메시지를 통해 다양한 데이터를 전송할 수 있다.

  • HTML, TEXT와 같은 문서 파일
  • 이미지, 음성, 영상과 같은 미디어 파일
  • JSON, XML 같은 API 형식의 데이터

이러한 특성 덕분에, 서버 간의 데이터 전송에도 HTTP를 많이 사용한다. 현재는 HTTP 시대라고 해도 과언이 아니다.

 

HTTP의 역사

  • HTTP/0.9 (1991년): GET 메서드만 지원, HTTP 헤더가 없는 아주 단순한 버전
  • HTTP/1.0 (1996년): 다양한 메서드와 헤더 추가
  • HTTP/1.1 (1997년): 가장 많이 사용되는 버전으로, 우리가 가장 많이 다루는 HTTP 버전
    • RFC2068 (1997) -> RFC2616 (1999) -> RFC7230~7235 (2014)로 발전
  • HTTP/2 (2015년): 성능 개선을 목표로 한 버전
  • HTTP/3 (진행 중): TCP 대신에 UDP를 사용하여 성능을 더욱 개선

기반 프로토콜

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

현재 가장 많이 사용되는 버전은 HTTP/1.1이지만, HTTP/2와 HTTP/3의 사용도 점차 증가하고 있다.

 

HTTP의 특징

  1. 클라이언트-서버 구조: 클라이언트가 요청을 보내고, 서버가 응답하는 구조
  2. 무상태 프로토콜: 서버는 이전 요청에 대한 정보를 저장하지 않으며, 각 요청은 독립적으로 처리된다.
  3. 비연결성: 요청과 응답이 끝나면 연결을 종료한다. 필요시 다시 연결을 생성한다.
  4. HTTP 메시지: 데이터를 주고받을 때 사용하는 기본 단위
  5. 단순함과 확장성: HTTP는 단순한 프로토콜이지만, 다양한 확장 가능성을 제공한다.

클라이언트 서버 구조

HTTP는 Request-Response 구조를 가진다. 이 구조에서 클라이언트와 서버 간의 상호작용은 다음과 같다.

  1. 클라이언트가 서버에 요청(Request)을 보낸다.
  2. 서버는 해당 요청을 처리하고, 결과를 응답(Response)으로 돌려준다.

이 간단한 흐름 덕분에 클라이언트와 서버는 각자의 역할을 명확히 분리할 수 있으며, 시스템 확장이 용이해진다.

 

클라이언트-서버 상호작용

  • 클라이언트는 서버에 요청을 보내고, 서버의 응답을 기다린다.
  • 서버는 요청에 대해 필요한 데이터를 처리하고 결과를 만들어 응답한다.

이 방식은 웹 애플리케이션뿐만 아니라, 모바일 애플리케이션, API 서비스 등 다양한 분야에서 활용된다.

 

무상태 프로토콜

HTTP는 무상태 프로토콜(Stateless Protocol)이다. 무상태란, 서버가 클라이언트의 이전 상태를 기억하지 않는다는 것을 의미한다.

 

무상태의 장점

  • 확장성: 서버가 클라이언트의 상태를 관리하지 않으므로, 서버를 쉽게 확장(스케일 아웃)할 수 있다.
    • 예를 들어, 서버에 트래픽이 몰리면 새로운 서버를 추가하여 부하를 분산할 수 있다.

무상태의 단점

  • 추가 데이터 전송: 서버가 클라이언트의 상태를 기억하지 않기 때문에, 클라이언트는 매 요청마다 필요한 정보를 서버에 다시 전송해야 한다.

무상태 프로토콜의 이러한 특성은 웹 서비스의 확장성을 높이는 데 중요한 역할을 하지만, 클라이언트 측에서 더 많은 정보를 관리하고 전송해야 한다는 부담도 존재한다.

 

Stateful, Stateless

Stateful은 서버가 클라이언트의 상태를 기억하고 유지하는 방식이다. 서버가 클라이언트의 이전 요청과 상태를 계속해서 기억하기 때문에, 다음 요청에서 이를 활용할 수 있다.

 

상태 유지 - Stateful

Stateful은 서버가 클라이언트의 상태를 기억하고 유지하는 방식이다. 서버가 클라이언트의 이전 요청과 상태를 계속해서 기억하기 때문에, 다음 요청에서 이를 활용할 수 있다.

예시

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

이처럼, 클라이언트가 보낸 이전 요청에 대한 상태를 점원이 계속 유지하며, 구매 과정이 이어진다.

 

상태 유지(Stateful)의 문제

중간에 점원이 바뀌면 상태가 이어지지 않아 문제가 발생할 수 있다.

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

서버가 중간에 바뀌게 되면 상태가 이어지지 않아 요청을 제대로 처리할 수 없게 된다.

 

무상태 - Stateless

Stateless는 서버가 클라이언트의 상태를 기억하지 않는 방식이다. 모든 요청은 독립적이며, 클라이언트가 매 요청마다 필요한 모든 정보를 다시 보내야 한다.

예시

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

서버가 상태를 기억하지 않기 때문에, 클라이언트는 매 요청마다 필요한 모든 정보를 다시 보내야 한다. 하지만 서버가 바뀌더라도 문제가 발생하지 않는다.

 

무상태(Stateless)의 장점

  • 서버 간 상태 공유가 필요 없으므로, 중간에 서버가 바뀌어도 상관없다.
  • 트래픽이 증가해도 서버를 쉽게 추가하여 확장(스케일 아웃)할 수 있다.
  • 중간에 서버가 장애가 나더라도, 다른 서버로 요청을 전송하면 된다.

실무에서의 Stateless 한계

모든 시스템을 무상태로 설계할 수는 없다. 일부 상태를 유지해야 하는 상황도 존재한다.

  • 무상태 예시: 로그인 필요 없는 단순 서비스 소개 화면
  • 상태 유지 예시: 로그인한 사용자의 상태를 유지하는 서비스

일반적으로 로그인된 상태는 서버가 유지해야 하며, 이를 위해 브라우저 쿠키와 서버 세션을 활용한다. 하지만 상태 유지는 최소한으로 하는 것이 바람직하다.

 

비 연결성 (connectionless)

연결을 유지하는 모델

서버가 클라이언트와 연결을 유지하는 방식이다. 이 방식에서는 클라이언트가 요청을 보내고, 서버는 응답을 보낸 뒤에도 연결을 계속 유지한다. 서버는 클라이언트와의 연결을 유지하면서 계속 자원을 사용하게 된다.

 

연결을 유지하지 않는 모델

HTTP는 기본적으로 연결을 유지하지 않는 모델이다. 클라이언트가 요청을 보내고, 서버가 응답을 보내면 그 즉시 연결을 끊는다. 이 방식은 서버 자원을 효율적으로 사용할 수 있도록 해준다.

 

일반적으로 사용자는 초 단위 이하의 빠른 속도로 서버에 요청하고, 동시에 서버에서 처리되는 요청 수는 상대적으로 적기 때문에 이 모델이 효율적이다.

 

비 연결성의 한계와 극복

비 연결성 모델의 한계는 TCP/IP 연결을 매번 새로 맺어야 한다는 것이다. 이 과정에서 3-way handshake가 필요하기 때문에 시간이 추가로 소요된다.

 

웹 브라우저로 사이트를 요청하면 HTML, 자바스크립트, CSS, 이미지 등 많은 자원이 함께 다운로드된다. 이를 해결하기 위해 HTTP 지속 연결(Persistent Connections)이 도입되었다. 지속 연결을 통해 서버는 여러 요청에 대해 한번 연결로 응답을 처리할 수 있게 되었고, 이는 HTTP/2와 HTTP/3에서 더 많은 최적화가 이루어졌다.

 

HTTP 초기 - 연결, 종료 낭비

초기 HTTP는 매번 연결을 맺고 종료하는 방식이어서 불필요한 자원 낭비가 많았다.

 

HTTP 지속 연결(Persistent Connections)

HTTP/1.1부터는 지속 연결을 통해 여러 자원을 한 번에 효율적으로 전송할 수 있게 되었다. 한 번 연결하면 여러 요청과 응답을 그 연결 안에서 처리한다.

스테이스리스를 기억하자

서버 개발자들이 어려워하는 대표적인 업무 중 하나는 정확히 같은 시간에 발생하는 대규모 트래픽을 처리하는 일이다. 대량의 트래픽이 짧은 시간 안에 몰리면서 서버에 큰 부담을 주기 때문이다.

 

예시

  • 선착순 이벤트
  • 명절 KTX 예약
  • 학과 수업 등록

사례

예를 들어, 저녁 6시에 선착순 1000명 치킨 할인 이벤트가 진행된다고 하면, 수만 명이 동시에 서버에 요청을 보내는 상황이 발생한다. 서버가 이처럼 갑작스럽게 몰리는 대량의 요청을 처리하기 위해서는 스테이스리스(stateless) 설계가 유리하다.

스테이스리스 시스템은 서버가 클라이언트의 상태를 유지하지 않기 때문에, 각각의 요청이 독립적으로 처리된다. 서버 자원을 효율적으로 사용하면서도, 필요한 경우 서버를 쉽게 확장(스케일 아웃)할 수 있어 대규모 트래픽 상황에서도 비교적 안정적으로 시스템을 운영할 수 있다.

 

HTTP 메시지

모든 데이터는 HTTP 메시지를 통해 전송된다. HTML, TEXT부터 이미지, 음성, 영상 파일 그리고 JSON, XML 같은 데이터 형식까지 다양한 형태의 데이터를 HTTP로 주고받을 수 있다. 오늘날 대부분의 데이터 통신은 HTTP로 이루어진다.

HTTP 메시지의 구조

시작 라인 - 요청 메시지

  • start-line = request-line / status-line
  • request-line = method SP(공백) request-target SP HTTP-version CRLF(엔터)
  • HTTP 요청 메시지는 크게 세 가지로 구성된다:
    1. HTTP 메서드: 서버가 수행할 동작을 지정 (예: GET, POST, PUT, DELETE 등)
    2. 요청 대상: 절대경로 또는 쿼리 파라미터로 지정된 리소스 (예: /search?q=hello&hl=ko)
    3. HTTP 버전: HTTP 메시지가 사용하는 프로토콜의 버전 (예: HTTP/1.1)

요청 메시지 - HTTP 메서드

  • GET: 리소스를 조회할 때 사용
  • POST: 서버가 요청 내용을 처리하도록 할 때 사용

요청 메시지 - 요청 대상

  • 절대 경로: "/"로 시작하는 경로
  • 예: /search, /users
  • 쿼리 파라미터로 요청을 상세화할 수 있음 (예: /search?q=hello)

요청 메시지 - HTTP 버전

  • 예: HTTP/1.1, HTTP/2

시작 라인 - 응답 메시지

  • status-line = HTTP-version SP status-code SP reason-phrase CRLF
  • 응답 메시지도 세 가지로 구성된다:
    1. HTTP 버전
    2. 상태 코드: 서버가 요청을 성공적으로 처리했는지 여부를 나타냄 (예: 200 OK, 404 Not Found, 500 Internal Server Error)
    3. 이유 문구: 사람이 읽을 수 있는 간단한 설명

상태 코드 예시

  • 200: 성공
  • 400: 클라이언트의 요청 오류
  • 500: 서버 내부 오류

HTTP 헤더

  • header-field = field-name ":" OWS (OWS: 공백 허용)
  • field-name은 대소문자를 구분하지 않는다.

HTTP 헤더의 용도

HTTP 헤더는 다양한 정보를 전달하는 데 사용된다. 다음은 그 용도의 예시다.

  • 메시지 바디의 내용과 크기
  • 데이터 압축 정보
  • 인증 관련 정보
  • 요청한 클라이언트(브라우저) 정보
  • 서버 애플리케이션 정보
  • 캐시 관리 정보 등

표준 HTTP 헤더의 종류는 매우 많으며, 필요에 따라 임의의 헤더도 추가할 수 있다.

  • 예: helloworld: hihi

참고: 표준 헤더 목록은 https://en.wikipedia.org/wiki/List_of_HTTP_header_fields에서 확인 가능하다.

HTTP 메시지 바디

HTTP 메시지 바디에는 실제 전송할 데이터가 담긴다. 여기에는 다음과 같은 종류의 데이터를 포함할 수 있다.

  • HTML 문서
  • 이미지 파일
  • 영상 파일
  • JSON 데이터 등

모든 데이터는 바이트로 표현할 수 있으며, HTTP를 통해 전송이 가능하다.

단순함 확장 가능

HTTP는 매우 단순한 프로토콜이다. 스펙도 비교적 간단하게 읽을 수 있다. 이 단순함이 HTTP의 성공 요인 중 하나이다. 단순함 덕분에 다양한 상황에 확장 가능한 프로토콜이 되었다.

성공한 표준 기술은 대부분 단순하면서도 확장 가능한 기술이다.

HTTP 정리

  • HTTP 메시지를 통해 거의 모든 데이터를 전송할 수 있다.
  • HTTP의 역사 중 HTTP/1.1을 기준으로 학습해야 한다.
  • 클라이언트-서버 구조를 기반으로 하고, 무상태 프로토콜(Stateless)을 따른다.
  • HTTP는 단순하지만 확장 가능성이 매우 높다.
  • 지금은 HTTP 시대다.

'FrontEnd > HTTP' 카테고리의 다른 글

[HTTP] HTTP 상태코드  (0) 2024.10.08
[HTTP] HTTP 메서드 활용  (1) 2024.10.07
[HTTP] HTTP 메서드  (1) 2024.10.06
[HTTP] URI와 웹 브라우저 요청 흐름  (3) 2024.10.06
[HTTP] 인터넷 네트워크  (1) 2024.10.06