~/tech-blog/posts/http-basics — zsh
지금 --명이 보고 있습니다오늘 --누적 --

HTTP 기본

이전에 URI와 웹 브라우저 요청 흐름에 대해 작성하였습니다. 그 글에서는 URL 문법과, 웹 브라우저가 HTTP 메시지를 TCP/IP 패킷에 담아 서버와 주고받는 흐름을 정리하였습니다. 오늘은 HTTP의 역사와 특징, 클라이언트 서버 구조, 무상태 프로토콜과 비연결성, 그리고 HTTP 메시지의 구조에 대해 정리하도록 하겠습니다.

HTTP

HTTP는 HyperText Transfer Protocol의 약자이며, HTTP 메시지에 모든 것을 전송합니다.

  • HTML, TEXT
  • IMAGE, 음성, 영상, 파일
  • JSON, XML (API)
  • 거의 모든 형태의 데이터를 전송할 수 있습니다.
  • 서버 간에 데이터를 주고받을 때도 대부분 HTTP를 사용합니다.
  • 지금은 HTTP의 시대입니다.

HTTP의 역사

  • HTTP/0.9 1991년: GET 메서드만 지원, HTTP 헤더 없음
  • HTTP/1.0 1996년: 메서드, 헤더 추가
  • HTTP/1.1 1997년: 가장 많이 사용되는, 가장 중요한 버전
    • RFC2068(1997) → RFC2616(1999) → RFC7230~7235(2014)
  • HTTP/2 2015년: 성능 개선
  • HTTP/3: TCP 대신 UDP 사용, 성능 개선(강의 당시에는 진행 중이었고, 2022년 RFC 9114로 표준이 되었습니다)

HTTP/1.1에 대부분의 기능이 들어 있고, HTTP/2와 HTTP/3는 거의 성능 개선에 초점이 맞춰져 있습니다. 그래서 HTTP/1.1을 가장 중요하게 생각합니다.

기반 프로토콜

  • TCP: HTTP/1.1, HTTP/2
  • UDP: HTTP/3
  • 현재 HTTP/1.1을 주로 사용하며, HTTP/2와 HTTP/3의 사용도 점점 증가하고 있습니다.

TCP는 3-way handshake와 많은 정보가 포함되어 있어 느립니다. 그래서 성능 최적화를 위해 나온 방식이 HTTP/3의 UDP 방식입니다.

구글을 비롯한 주요 서비스에서도 HTTP/3(H3) 사용이 늘어나는 추세입니다. TCP와 UDP의 차이는 인터넷 네트워크에서 정리하였습니다.

HTTP 특징

HTTP의 특징은 아래와 같고, 차례대로 정리하겠습니다.

  • 클라이언트 서버 구조
  • 무상태 프로토콜(스테이트리스), 비연결성
  • HTTP 메시지
  • 단순함, 확장 가능

클라이언트 서버 구조

  • Request-Response 구조입니다.
  • 클라이언트는 서버에 요청을 보내고 응답을 대기합니다.
  • 서버는 요청에 대한 결과를 만들어 응답합니다.
  • 클라이언트는 UI/UX를 그리는 데 집중하고, 비즈니스 로직 같은 중요한 데이터는 서버에서 구현해 전달합니다.

무상태 프로토콜

무상태 프로토콜은 스테이트리스(stateless)라고도 합니다.

  • 서버가 클라이언트의 상태를 보존하지 않습니다.
  • 장점: 서버 확장성이 높습니다(스케일 아웃).
  • 단점: 클라이언트가 추가 데이터를 전송해야 합니다.

Stateful, Stateless 차이

  • 상태 유지: 상태를 서버에서 저장합니다. 중간에 서버가 바뀌면 안 됩니다.
  • 무상태: 상태를 클라이언트 측에서 저장합니다. 중간에 서버가 바뀌어도 상관없습니다. 그래서 스케일 아웃(수평 확장)에 유리합니다.

같은 클라이언트의 두 번째 요청이 다른 서버로 갔을 때를 비교하면 다음과 같습니다.

상태 유지 방식은 서버 A가 저장한 상태를 서버 B가 알지 못해 두 번째 요청을 처리하지 못하고, 무상태 방식은 클라이언트가 요청마다 필요한 데이터를 함께 보내 어느 서버든 처리할 수 있는 비교눌러서 원본 크기로 보기

무상태 방식은 요청에 필요한 데이터가 요청 안에 모두 들어 있기 때문에, 중간에 서버가 바뀌거나 서버를 늘려도 그대로 처리할 수 있습니다.

Stateless의 한계

  • 모든 것을 무상태로 설계할 수 있는 경우도 있고 없는 경우도 있습니다.
  • 무상태 예: 로그인이 필요 없는 단순한 서비스 소개 화면
  • 상태 유지 예: 로그인
  • 로그인한 사용자의 경우, 로그인했다는 상태를 서버에 유지해야 합니다.
  • 일반적으로 브라우저 쿠키와 서버 세션 등을 사용해서 상태를 유지합니다.
  • 상태 유지는 최소한만 사용합니다.

비연결성(connectionless)

HTTP는 기본적으로 연결을 유지하지 않는 모델입니다.

  • 일반적으로 초 단위 이하의 빠른 속도로 응답합니다.
  • 1시간 동안 수천 명이 서비스를 사용해도, 실제 서버에서 동시에 처리하는 요청은 수십 개 이하로 매우 적습니다.
    • 예: 웹 브라우저에서 계속 연속해서 검색 버튼을 누르지는 않습니다.
  • 서버 자원을 매우 효율적으로 사용할 수 있습니다.

비연결성의 한계와 극복

  • TCP/IP 연결을 새로 맺어야 합니다(3-way handshake 시간 추가).
  • 웹 브라우저로 사이트를 요청하면 HTML뿐 아니라 자바스크립트, CSS, 이미지 등 수많은 자원이 함께 다운로드됩니다.
  • 지금은 HTTP 지속 연결(Persistent Connections)로 이 문제를 해결했습니다.
  • HTTP/2, HTTP/3에서는 더 많은 최적화가 이루어졌습니다.

자원마다 연결을 새로 맺는 경우와 지속 연결을 사용하는 경우를 비교하면 다음과 같습니다.

연결을 유지하지 않으면 HTML, 자바스크립트, 이미지를 받을 때마다 3-way handshake로 연결하고 종료하기를 반복하고, 지속 연결을 사용하면 한 번 맺은 연결로 여러 자원을 차례로 요청하고 응답받는 비교눌러서 원본 크기로 보기

위쪽은 자원을 받을 때마다 연결을 맺는 시간이 더해지고, 아래쪽은 한 번 맺은 연결로 여러 자원을 주고받기 때문에 그 시간이 줄어듭니다.

스테이트리스와 대용량 트래픽

서버 개발자들이 어려워하는 업무가 있습니다.

  • 정말 같은 시간에 딱 맞추어 발생하는 대용량 트래픽
  • 예: 선착순 이벤트, 명절 KTX 예약, 학과 수업 등록
  • 예: 저녁 6시 선착순 1000명 치킨 할인 이벤트 → 수만 명이 동시에 요청

HTTP 메시지

모든 것이 HTTP

앞에서 정리한 것처럼 HTTP 메시지에는 모든 것을 전송할 수 있습니다.

  • HTML, TEXT
  • IMAGE, 음성, 영상, 파일
  • JSON, XML
  • 거의 모든 형태의 데이터를 전송할 수 있습니다.
  • 서버 간에 데이터를 주고받을 때도 대부분 HTTP를 사용합니다.
  • 지금은 HTTP의 시대입니다.

HTTP 메시지는 시작 라인, 헤더, 메시지 바디로 구성됩니다. 요청 메시지와 응답 메시지를 나란히 그리면 다음과 같습니다.

요청 메시지는 GET /search?q=hello&hl=ko HTTP/1.1 시작 라인과 Host 헤더로, 응답 메시지는 HTTP/1.1 200 OK 시작 라인과 Content-Type 헤더, 빈 줄 다음의 HTML 메시지 바디로 구성되는 HTTP 메시지 구조눌러서 원본 크기로 보기

두 메시지 모두 시작 라인, 헤더, 빈 줄, 메시지 바디 순서로 구성되고, 시작 라인의 형식만 요청과 응답이 다릅니다. 각 부분을 차례로 정리하겠습니다.

시작 라인

  • Start-line = request-line(요청 메시지) / status-line(응답 메시지)

요청 메시지의 시작 라인은 아래와 같습니다.

  • request-line = method SP(공백) request-target SP HTTP-version CRLF(엔터)
  • HTTP 메서드
    • 종류: GET, POST, PUT, DELETE 등
    • 서버가 수행해야 할 동작을 지정합니다.
      • GET: 리소스 조회
      • POST: 요청 내역 처리
  • 요청 대상 (/search?q=hello&hl=ko)
    • absolute-path[?query] (절대경로[?쿼리])
    • 절대경로는 "/"로 시작하는 경로입니다.
    • 참고: *, http://...?x=y와 같이 다른 유형의 경로 지정 방법도 있습니다.
  • HTTP Version

응답 메시지의 시작 라인은 아래와 같습니다.

  • status-line = HTTP-version SP(공백) status-code SP reason-phrase CRLF(엔터)
  • HTTP 버전
  • HTTP 상태 코드: 요청의 성공, 실패를 나타냅니다.
    • 200: 성공
    • 400: 클라이언트 요청 오류
    • 500: 서버 내부 오류
  • 이유 문구: 사람이 이해할 수 있는 짧은 상태 코드 설명 글입니다.

HTTP 헤더

  • header-field = field-name":" OWS field-value OWS (OWS: 띄어쓰기 허용)
  • field-name은 대소문자를 구분하지 않습니다.
  • 용도
    • HTTP 전송에 필요한 모든 부가 정보입니다.
    • 예: 메시지 바디의 내용, 메시지 바디의 크기, 압축, 인증, 요청 클라이언트(브라우저) 정보, 서버 애플리케이션 정보, 캐시 관리 정보 등
    • 표준 헤더가 매우 많습니다.
    • 필요하면 임의의 헤더를 추가할 수 있습니다.
      • helloworld: hihi

HTTP 메시지 바디

실제 전송할 데이터입니다. HTML 문서, 이미지, 영상, JSON 등 byte로 표현할 수 있는 모든 데이터를 전송할 수 있습니다.

서블릿이 이 메시지를 파싱해 HttpServletRequest로 제공하는 방식은 서블릿에서 정리하였습니다.

마무리

오늘은 HTTP의 역사와 기반 프로토콜, 클라이언트 서버 구조, 무상태 프로토콜과 비연결성, 그리고 시작 라인·헤더·메시지 바디로 이루어진 HTTP 메시지 구조에 대해 정리하였습니다. 서버를 수평 확장하려면 상태 유지를 최소한으로 두어야 한다는 점을 기억해 두면 좋을 것 같습니다. 다음 글에서는 HTTP 메서드에 대해 정리하도록 하겠습니다.

이 글은 인프런 김영한 님의 모든 개발자를 위한 HTTP 웹 기본 지식을 들으며 정리한 노트입니다.

이 시리즈 · HTTP 웹 기본 지식
전체 5편

댓글

GitHub 계정으로 로그인하시면 댓글과 질문을 남기실 수 있습니다. 남겨 주신 글은 이 저장소의 Discussions에 쌓입니다.

● main 231 posts UTF-8 LF © 2026 코징 RSS · GitHub