levi

리바이's Tech Blog

Tech BlogPortfolioBoard
AllActivitiesJavascriptTypeScriptNetworkNext.jsReactWoowacourseAlgorithm
COPYRIGHT ⓒ eunwoo-levi
eunwoo1341@gmail.com

📚 목차

    [Network] HTTP 1.0 VS 1.1 vs 2.0 vs 3.0 딥다이브

    ByEunwoo
    2025년 9월 10일
    network

    인프라는 백엔드 뿐만 아니라 프론트엔드 엔지니어 입장에서도 매우 중요하다고 최근에 느낀다.

    "지금 **우리 요청이 실제로 어떤 길(프로토콜)**로 가는지조차 모를 때"
    "HTTP라서 브라우저 기능(Service Worker, 일부 API)이 아예 안 켜질 때"
    "혼합 콘텐츠(HTTPS 페이지에 HTTP 리소스) 때문에 이미지·폰트가 그냥 차단될 때"
    "CORS/쿠키/헤더가 어쩌다 전송되고, 왜 어떤 요청만 막히는지 이해가 안 될 때"
    "CDN이 뭘 캐시했고 왜 HIT/MISS인지, 백엔드 에러와 프록시 에러가 구분이 안 될 때"
    "인증서가 만료되거나 체인이 꼬여서 그냥 접속 자체가 안 될 때"

    이건 최적화의 문제가 아니라 웹이 굴러가는 최소 단위—HTTP와 HTTPS, 그리고 1.0/1.1/2/3 버전의 기본 규칙을 모르면 생기는 막힘이다.
    그래서 이 글에서는 왜 요청이 통하고/막히는지, 어떤 제약에서 브라우저가 움직이는지 등 인프라를 이해하는데 필요한 웹의 핵심 프로토콜인 http의 진화와 특징에 대해 깊게 알아보게 되었다.

    HTTPS (Hyper Text Transfer Protocol Secure)란?

    HTTPS = HTTP + TLS

    즉, 평문 프로토콜인 HTTP 위에 **TLS(Transport Layer Security)**를 덧씌워 암호화·무결성·서버 인증을 제공하는 방식이다.

    그럼 HTTPS이 왜 필요한 것인가?

    • 암호화(Confidentiality): 요청/응답 본문과 대부분의 헤더가 제3자에게 읽히지 않는다.
    • 무결성(Integrity): 전송 중 데이터가 바뀌면 바로 탐지된다.
    • 서버 인증(Authentication): 브라우저가 서버의 인증서를 검증해 "정말 그 도메인 맞다"를 확인한다.

    HTTPS는 "빠르게 만들기 위한 옵션"이 아니라, 웹 기능의 전제이다. 혼합 콘텐츠 차단, 일부 브라우저 API(예: Service Worker), 쿠키 보안 속성 등도 HTTPS를 전제로 동작한다.

    HTTP/1.0: 연결 비지속의 시대

    HTTP/1.0은 1996년에 출시되었으며, 이전 버전인 0.9보다 훨씬 견고한 프로토콜이 되었다.

    주요 특징

    • HTTP/1.0은 **헤더(Header)**를 도입하여 프로토콜의 유연성과 확장성을 높였고, 메타데이터 전송이 가능해졌다.
    • 요청 라인에 명시적으로 버전을 알리며, 응답에는 요청 처리 상태를 확인할 수 있는 **상태 코드(Status code)**가 포함되었다.
    • GET 외에 서버에 데이터를 전송하는 POST와 메타데이터만 검색하는 HEAD 메서드가 추가되었다.
    • Content-type 필드 덕분에 일반 HTML 파일 외의 다른 문서 유형을 전송할 수 있게 되었다.

    단점

    • HTTP/1.0은 서버와 클라이언트 간의 Connection을 지속하지 않는다
    • 단 1개의 요청을 처리할 때마다 DNS 조회, TCP 3-way handshake, SSL/TLS handshake와 같이 네트워크 지연 시간을 늘리는 행위를 반복적으로 수행해야 했다. 이는 매우 불필요한 행위였다

    HTTP/1.1: 지속 연결과 HOL Blocking의 시작

    HTTP/1.1은 1997년, 1.0 출시 후 단 1년 만에 등장하여 1.0의 문제점을 개선한 버전이다

    주요 개선점 (Keep-Alive)

    • Keep-Alive 기능을 통해 매 요청마다 Connection을 새로 맺지 않기 위해 서버와 클라이언트 간의 연결을 유지한다.
    • 이 덕분에 하나의 TCP Connection을 통해 여러 개의 요청과 응답을 처리할 수 있게 되었으며, Keep-Alive는 HTTP/1.1의 기본 동작에 포함되었다.
    • 클라이언트가 연결을 끊고 싶다면 Connection: close를 헤더에 포함시켜 명시적으로 서버에 요청할 수 있다.
    • HTTP/1.1에서는 Host Header가 사양에 따라 필수로 요구된다

    파이프라이닝과 그 한계

    HTTP/1.1은 클라이언트가 응답을 기다리지 않고도 단일 TCP 연결을 통해 여러 HTTP 요청을 보내는 파이프라이닝 기능도 있었다.
    하지만 파이프라이닝은 요청 순서에 맞게 응답을 받아야 하는 치명적인 단점이 있었다.
    만약 [요청1, 요청2, 요청3] 순서로 요청했으나 응답2가 먼저 도착했더라도, 응답2는 응답1이 오기 전까지 처리되지 않고 기다려야 했다.
    이처럼 동일한 연결 내에서 특정 요청 때문에 후속 요청이 영향을 받는 현상을 **Head of Line Blocking (HOL Blocking)**이라고 한다.
    파이프라이닝은 구현이 어려웠고 프록시 서버 처리 문제 때문에 크롬, 파이어폭스 같은 브라우저들은 결국 이 기능을 지원하지 않게 되었다.

    HTTP/2.0: 멀티플렉싱으로 애플리케이션 계층 해결

    HTTP/2.0은 2015년에 공식 출시되었으며, 프로토콜 성능 개선에 중점을 두었다

    바이너리 프로토콜 및 스트림 도입

    HTTP/1.1이 메시지를 텍스트(text)로 보냈다면, HTTP/2.0은 메시지를 바이너리화하여 전송한다.
    메시지는 **헤더 프레임(header frame)**과 **데이터 프레임(data frame)**이라는 데이터 단위로 만들어지며, 각 프레임에 Stream Sequence 번호를 붙여 구분한다.
    같은 번호를 가진 프레임들을 묶어 **스트림(Stream)**이라는 개념으로 구분 짓는다.

    멀티플렉싱 (Multiplexing)

    스트림 개념을 도입한 덕분에 HTTP/2.0은 멀티플렉싱을 통해 단일 연결(TCP Connection)에서 여러 개의 요청과 응답을 비동기적으로 처리할 수 있게 되었다.
    이로써 HTTP/1.1에서 응답 순서 때문에 후속 요청이 영향을 받던 Application Layer의 HOL Blocking 문제를 해결할 수 있었다.

    남겨진 문제 (TCP HOL Blocking)

    HTTP/2.0은 여전히 TCP Connection 위에서 프레임들을 주고받기 때문에, Transport Layer(전송 계층)에서 발생하는 HOL Blocking은 해결할 수 없었다.
    예를 들어, 특정 스트림의 패킷이 손실되면, 해당 패킷이 올 때까지 뒤따르는 다른 스트림의 패킷들(데이터)까지 여전히 기다리게 되었다

    예시를 간단히 적어보자면

    HTTP/1.1 (한 연결, 줄 서기)
    [ AAAAAAA ] [ BBB ] [ CCCCC ]   ← A 끝나야 B, B 끝나야 C
    
    HTTP/2/3 (한 연결, 멀티플렉싱)
    [ A A A A ]
    [  B B  ]     ← A/B/C 조각(프레임)들이 번갈아 섞여 흐름
    [   C  C C ]
    • 요청·응답은 더 작은 프레임으로 쪼개져서, 스트림 ID로 구분되어 한 연결 안에서 섞여 흐른다.
    • 서버와 클라이언트는 각 스트림마다 **흐름 제어(Flow Control)**와 우선순위 힌트로 어떤 걸 먼저 많이 보내줄지 조율할 수 있다.

    Server Push

    클라이언트가 요청하기 전에 서버가 클라이언트에 미리 리소스를 보내 네트워크 요청을 줄일 수 있을 것으로 예상되는 Server Push 기능도 있었다.
    하지만 클라이언트가 서버가 보낸 리소스를 알지 못하고 다시 요청하는 등의 문제로 인해, Google은 2022년 10월 Chrome에서 Server push 기능을 제거했다.

    HTTP/3.0: QUIC으로 전송 계층의 한계를 돌파

    HTTP/3.0은 2020년에 첫 드래프트가 발표되었으며, TCP에 의존했던 이전 버전들과 달리 새로운 전송 계층 프로토콜을 사용하는 것이 핵심이다

    QUIC 프로토콜 사용

    • HTTP/3.0은 TCP HOL Blocking을 해결하기 위해 TCP 대신 UDP에 기반한 QUIC (Quick UDP Internet Connections) 프로토콜을 사용한다.
    • QUIC은 네이티브 멀티플렉싱 기능과 암호화(built-in encryption) 기능을 내장한 전송 계층 프로토콜이다

    HOL Blocking의 종식 (Transport Layer)

    QUIC 프로토콜을 사용하면서 각 스트림들이 독립적이게 되었다.

    HTTP/2에서 TCP 기반에서는 패킷 하나가 손실되면 후속 패킷 전체가 막히지만, HTTP/3에서 QUIC 기반에서는 손실된 패킷과 관련된 일부 패킷만 Blocking 되고 나머지 스트림은 영향을 받지 않는다. 이로써 Transport Layer에서의 HOL Blocking 문제를 해결했다.

    Zero RTT Connection 달성

    HTTP/3.0의 QUIC은 서버와 클라이언트 간의 연결을 맺는 데 **0 RTT(Round-Trip Time)**를 달성한다.
    TCP 연결은 1 RTT, TCP + TLS 연결은 2~3 RTT가 걸리는 것에 비해, HTTP/3.0은 연결과 동시에 데이터를 전송할 수 있게 되었다.
    HTTP/3.0은 항상 암호화된 연결을 생성하므로, HTTP/2.0에서 HTTPS를 항상 사용하는 것과 유사하다.

    마무리

    이번 글에서는 웹이 기본적으로 어떻게 통신하는지에 대해 알아보았다.

    HTTP는 웹이 “통하는 방식” 그 자체다. 메서드·헤더·버전·보안·중간자 규칙을 이해하면, 기능이 왜 켜지고/막히는지 설명할 수 있고, 팀과 같은 언어로 문제를 풀 수 있다.

    이때까지 배운 내용들을 아래와 같이 정리해보았다.

    • HTTP/1.0/1.1은 “연결을 어떻게 열고 유지하나”, “왜 줄을 서는가”를 보여준다.
    • HTTP/2는 “한 연결 안에서 여러 일을 동시에” 하게 만든 멀티플렉싱의 의미를 알려준다.
    • HTTP/3는 “왜 TCP를 벗어나 QUIC으로 갔는가”—손실/모바일 환경에서 덜 막히게 하려는 시도의 결과다.
    구분전송 방식다중화헤더 압축우선순위HOL Blocking핸드셰이크서버푸시
    HTTP/1.0TCP 1요청=1연결✗✗✗심각(요청/연결 단위)TCP✗
    HTTP/1.1TCP 지속 연결(keep-alive)파이프라이닝(비권장)✗(사실상 없음)연결 단위 HOL 지속TCP✗
    HTTP/2TCP 1연결 다중화(스트림)멀티플렉싱HPACK(우선순위/가중치, 구현차)TCP HOL 존재(연결 단위)TCP + TLS 보편△(사양 존재, 실전 비권장)
    HTTP/3QUIC(UDP 기반)멀티플렉싱QPACK개선됨HOL 완화(스트림 독립)TLS 1.3 내장(0-RTT)(사양 無; 푸시는 사실상 폐기 수순)
    HTTPSHTTP 위에 TLS––––TLS 핸드셰이크–
    Posted innetwork
    Written byEunwoo