사전 HTTP-3
프로토콜

HTTP-3

gabury1고친 사람 github-actions[bot]

HTTP/3

HTTP/3 은 웹의 요청과 응답을 나르는 세 번째 전송 규칙입니다. 앞선 판들은 아래층이 순서를 지켜 날라 준다는 성질에 기대고 있어서, 조각 하나가 사라지면 그와 상관없는 요청까지 함께 멈췄습니다. HTTP/3 은 그 아래층을 갈아 끼워 순서를 요청마다 따로 지키게 했습니다.

쉽고 빠른 이해

HTTP/3 은 브라우저와 서버가 주고받는 요청과 응답을 나르는 세 번째 전송 규칙입니다. 주고받는 내용은 앞선 판과 같고, 그것을 선 위로 실어 나르는 방법만 다릅니다.

이게 없으면 조각 하나가 중간에서 사라질 때 그와 아무 상관이 없는 요청까지 같이 멈춥니다. 앞선 판은 순서를 지켜 나르는 일을 아래층에 맡겨 두어서 그 멈춤을 스스로 풀 수 없었습니다.

어떻게 도나:

  1. 순서를 안 지키는 단순한 전송을 아래에 깔고, 순서 지키는 일은 그 위에서 직접 합니다
  2. 요청 하나가 통로 하나를 쓰고, 통로마다 순서를 따로 셉니다
  3. 조각이 사라지면 그 통로만 기다리고 나머지 통로는 계속 흐릅니다
  4. 연결을 여는 인사와 암호 열쇠를 맞추는 인사를 한 묶음으로 끝냅니다

대가도 있습니다. 순서와 재전송을 프로그램이 직접 챙기므로 같은 양을 나르는 데 드는 계산이 늘어납니다. 오가는 것이 거의 다 암호로 덮여 있어 중간에서 무슨 일이 벌어지는지 들여다보기 어렵고, 길목의 장비가 이 방식을 막아 두면 연결 자체가 안 되어 앞선 판으로 되돌아가야 합니다.

상세

HTTP/3(HyperText Transfer Protocol version 3)은 웹에서 요청과 응답을 주고받는 규칙인 HTTP(HyperText Transfer Protocol, 하이퍼텍스트 전송 프로토콜)의 세 번째 판입니다. 요청 방식과 헤더와 본문이라는 구성은 앞선 판에서 손대지 않았습니다. 바뀐 곳은 그 아래입니다 — TCP(Transmission Control Protocol, 전송 제어 프로토콜) 대신 QUIC 이라는 전송 규칙 위에 얹힙니다.

QUIC 은 Quick UDP Internet Connections 를 줄인 이름으로 시작했지만 지금은 그 풀이를 쓰지 않고 이름 그대로 부릅니다. QUIC 은 UDP(User Datagram Protocol, 사용자 데이터그램 프로토콜) 위에서 돌면서, 순서를 지키는 일과 다시 보내는 일과 암호로 덮는 일을 자기 안에 갖고 있습니다.

바꿀 까닭은 앞선 판인 HTTP/2 에 있었습니다. HTTP/2 도 연결 하나에 통로를 여럿 두어 요청을 겹쳐 보냈지만, 그 통로들이 결국 TCP 연결 하나를 지났습니다. 중간에서 조각 하나가 사라지면 TCP 는 그것이 다시 올 때까지 뒤에 도착한 것을 위로 올려 주지 않고, 사라진 조각과 상관없는 통로까지 같이 멈췄습니다. 이 현상을 헤드 오브 라인 블로킹이라고 부릅니다.

아래에서는 바뀐 아래층, 요청마다 따로 도는 통로, 그 위를 흐르는 조각, 헤더를 줄이는 압축, 한 번의 요청과 응답, 주소가 바뀌어도 이어지는 연결, 이 판으로 말할 상대를 찾아내는 방법, 그리고 이 판이 맞는 때를 차례로 봅니다.

층이 이렇게 바뀌었다

바뀐 것은 무슨 일을 하느냐가 아니라 그 일을 누가 맡느냐입니다. 눈에 띄는 것은 암호 줄입니다 — 앞선 판에서 TLS(Transport Layer Security, 전송 계층 보안)는 TCP 위에 따로 얹는 층이었는데, QUIC 은 그것을 자기 안에 품습니다. 그래서 HTTP/3 에는 암호를 안 쓰는 갈래가 없습니다.

아래 표는 같은 일을 두 판이 각각 어디에 맡기는지 늘어놓은 것입니다.

하는 일 HTTP/2 HTTP/3
요청과 응답의 뜻을 정하기 HTTP HTTP
통로를 여럿으로 나누기 HTTP/2 QUIC
순서 지키기와 다시 보내기 TCP QUIC
암호로 덮기 TLS QUIC
한 덩이씩 내보내기 TCP UDP

오른쪽 칸에서 QUIC 이 세 줄을 차지합니다. 통로를 나누는 일과 순서를 지키는 일이 한 곳에 모였다는 뜻이고, 이 한 줄이 아래 절 전부의 바탕입니다.

요청 하나에 통로 하나

QUIC 연결 안에는 스트림이라는 독립된 통로가 여럿 있습니다. 요청 하나와 그에 대한 응답 하나가 스트림 하나를 씁니다. 스트림마다 순서를 따로 세기 때문에, 한 스트림의 조각이 사라져도 다른 스트림은 그것을 기다리지 않습니다.

flowchart TD
    C["클라이언트"] --> CONN
    subgraph CONN["QUIC 연결 하나"]
        S0["스트림 0 · 문서 요청"]
        S4["스트림 4 · 그림 요청"]
        CTL["제어 스트림 · 연결 전체 설정"]
    end
    CONN --> DG["UDP 데이터그램"]
    DG --> SV["서버"]

스트림에는 번호가 붙습니다. 클라이언트가 연 것과 서버가 연 것, 그리고 양쪽이 주고받는 것과 한쪽으로만 흐르는 것이 번호로 갈립니다. 번호를 이렇게 나눠 두면 양쪽이 동시에 스트림을 열어도 같은 번호를 집는 일이 없습니다.

연결 전체에 걸리는 이야기는 따로 흐릅니다. 양쪽이 한쪽으로만 흐르는 스트림을 하나씩 열어 제어 스트림으로 쓰고, 설정을 알리거나 이제 새 요청을 안 받겠다고 말할 때 그 통로를 씁니다.

오가는 것은 프레임이다

스트림 위를 흐르는 조각을 프레임이라고 부릅니다. 프레임은 종류 하나와 길이 하나를 앞에 두고 그 뒤에 내용을 붙인 모양입니다. 종류와 길이는 값이 작으면 짧게, 크면 길게 적히는 가변 길이 정수라서 흔한 프레임일수록 머리가 짧아집니다.

프레임 종류는 앞선 판과 이름이 겹칩니다. 헤더를 싣는 HEADERS, 본문을 싣는 DATA, 연결 설정을 알리는 SETTINGS, 이제 새 요청을 안 받겠다고 알리는 GOAWAY 가 그것입니다.

대신 사라진 칸이 있습니다. 앞선 판의 프레임 머리에는 어느 스트림 것인지를 적는 칸이 있었는데 HTTP/3 프레임에는 없습니다. 스트림을 가르는 일도, 상대가 받을 수 있는 남은 양을 세는 흐름 제어도, 통로 하나를 취소하는 일도 전부 QUIC 이 자기 프레임으로 하기 때문입니다.

헤더를 줄이는 QPACK

한 페이지를 여는 요청 수십 개는 헤더가 거의 같습니다. user-agent 처럼 긴 값이 요청마다 글자 그대로 되풀이되면 그 양이 본문보다 커지기도 합니다. 그래서 두 판 모두 헤더를 표의 번호로 바꿔 보냅니다.

보내는 쪽과 받는 쪽은 같은 표를 하나씩 들고 있다가, 이미 한 번 보낸 이름과 값은 다음부터 번호로만 가리킵니다. 어려운 곳은 그 표를 고치는 순서입니다. 표를 고치라는 지시가 보낸 순서대로 도착해야 양쪽 표가 같아집니다.

앞선 판에서는 연결 하나가 순서를 지켜 줬으니 이 전제가 공짜였습니다. QUIC 은 스트림 사이의 순서를 보장하지 않으므로 그 전제가 깨집니다. 그래서 HTTP/3 은 QPACK(Field Compression for HTTP/3, 헤더 압축)이라는 다른 방식을 씁니다.

QPACK 은 표를 고치라는 지시를 전용 스트림 하나로 따로 보냅니다. 어떤 요청이 아직 안 도착한 표 항목을 가리키면 그 요청만 잠깐 기다리고, 다른 요청은 계속 처리됩니다. 기다리는 요청 수에는 상한을 둘 수 있고, 보내는 쪽이 아직 확인 안 된 항목을 안 가리키기로 하면 기다림이 아예 없습니다.

한 번의 요청과 응답

sequenceDiagram
    participant 클 as 클라이언트
    participant 서 as 서버
    클->>서: 연결 인사 + 암호 인사
    서->>클: 연결 인사 + 암호 인사 + 인증서
    클->>서: 제어 스트림 · SETTINGS
    클->>서: 스트림 0 · HEADERS · 요청 헤더
    서->>클: 스트림 0 · HEADERS · 응답 헤더
    서->>클: 스트림 0 · DATA · 응답 본문

앞의 두 줄이 연결을 여는 인사이자 암호 열쇠를 맞추는 인사입니다. 앞선 판은 이 둘을 따로 했습니다 — TCP 가 세 번 오가며 연결을 맺고, 그다음 TLS 가 다시 오가며 열쇠를 맞췄습니다. QUIC 은 둘을 겹쳐 한 번 오가는 것으로 끝냅니다.

한 번 이야기해 본 서버에는 열쇠를 다시 맞추지 않고 첫 왕복에 요청을 실어 보낼 수 있습니다. 대신 이 요청은 중간에서 가로챈 쪽이 그대로 다시 보내도 서버가 구별하지 못합니다. 그래서 같은 요청이 두 번 들어와도 결과가 달라지지 않는 요청에만 씁니다.

주소가 바뀌어도 이어지는 연결

TCP 연결은 양쪽의 주소와 포트, 네 값으로 식별됩니다. 그래서 휴대전화가 Wi-Fi 에서 이동통신으로 넘어가 주소가 바뀌면 그 연결은 끊기고 처음부터 다시 맺어야 합니다.

QUIC 은 연결에 따로 붙인 번호로 상대를 알아봅니다. 주소가 바뀌어도 이 번호가 같으면 서버는 같은 연결로 받아들이고, 새 길이 진짜 그 상대인지 한 번 물어 확인한 뒤 계속 씁니다. 주고받던 열쇠와 스트림이 살아 있어 보던 화면이 멈추지 않습니다.

이 판으로 말할 상대를 찾아내는 법

브라우저는 처음 붙는 서버가 HTTP/3 을 할 줄 아는지 모릅니다. 아래층이 아예 달라서, 앞선 판처럼 이미 맺은 연결 위에서 판을 맞춰 볼 수도 없습니다. 그래서 알아내는 길이 따로 있습니다.

첫째는 앞선 판으로 한 번 주고받아 보는 것입니다. 서버가 응답에 Alt-Svc 헤더를 붙여 이 이름은 HTTP/3 으로도 받는다고 알려 주면, 브라우저는 그 뒤부터 새 연결을 그쪽으로 엽니다.

둘째는 이름을 주소로 바꿀 때 같이 물어보는 것입니다. DNS(Domain Name System, 도메인 이름 체계)에 이 이름이 어떤 판을 받는지 적어 두는 레코드가 있어서, 주소를 찾는 그 한 번의 물음에 답이 같이 옵니다. 이러면 첫 연결부터 HTTP/3 으로 열 수 있습니다.

어느 쪽이든 마지막 확인은 연결을 맺을 때 합니다. 암호 인사를 나누며 ALPN(Application-Layer Protocol Negotiation, 응용 계층 프로토콜 협상)이라는 확장으로 판 이름을 주고받고, HTTP/3 은 거기서 h3 이라는 이름으로 불립니다.

언제 쓰고 언제 안 쓰나

얻는 것이 큰 쪽은 조각이 자주 사라지는 길과 요청이 많은 화면입니다. 이동통신처럼 손실이 잦은 길에서는 통로 하나의 손실이 나머지를 안 세우는 것이 그대로 체감으로 옵니다. 주소가 자주 바뀌는 휴대전화도 같은 까닭으로 얻는 쪽입니다.

반대로 데이터센터 안에서 서버끼리 부르는 통신은 얻는 것이 적습니다. 조각이 거의 안 사라지는 길이라 앞선 판이 겪던 멈춤 자체가 드물기 때문입니다.

대가도 있습니다. 순서와 재전송과 혼잡 조절을 운영체제 대신 프로그램이 챙기므로 같은 양을 나르는 데 계산이 더 듭니다. 오가는 것이 거의 다 암호로 덮여 있어 중간에서 떠 보아도 조각의 번호와 종류가 안 보이고, 들여다보려면 열쇠를 따로 뽑아 두어야 합니다.

길목이 막는 경우도 있습니다. 회사망이나 일부 통신망은 웹에 쓰이지 않던 이 전송을 걸러 버려서 연결이 아예 안 맺어집니다. 그래서 HTTP/3 을 켜는 서버도 앞선 판을 같이 열어 두고, 브라우저는 안 되면 그쪽으로 되돌아갑니다.

굴리는 쪽도 손이 갑니다. 여러 대에 나눠 주는 로드 밸런서는 주소와 포트로 같은 연결을 알아보던 방식을 연결 번호로 바꿔야 하고, 그러지 않으면 주소가 바뀐 연결이 엉뚱한 서버로 갑니다. 켜는 일 자체는 대개 인증서를 다루는 리버스 프록시 쪽 설정으로 끝납니다.

관련 항목

HTTP/3 을 정의하는 표준 문서

RFC 9114 · RFC 9204 · RFC 9000 · RFC 9110 · RFC 9460 · IETF

HTTP/3 연결을 이루는 구성 요소

스트림 · 프레임 · 제어 스트림 · 단방향 스트림 · 스트림 ID · SETTINGS 프레임

HTTP/3 이 헤더를 줄이는 데 쓰는 수단

QPACK · HPACK · 동적 표 · 정적 표 · 허프만 부호화 · 헤더

HTTP/3 이 얹히는 아래쪽 프로토콜

QUIC · UDP · TLS · IP · 소켓

HTTP/3 과 같은 쓰임을 두고 겨루는 전송 규칙

HTTP · HTTP/1.1 · HTTP/2 · 웹소켓 · gRPC

HTTP/3 이 풀려 한 문제와 그 전의 우회책

헤드 오브 라인 블로킹 · 멀티플렉싱 · 패킷 손실 · 혼잡 제어 · 도메인 샤딩

HTTP/3 연결이 주소 변화를 견디게 하는 장치

연결 ID · 연결 마이그레이션 · 경로 검증 · NAT · 0-RTT

HTTP/3 서버를 찾아내는 데 쓰는 수단

Alt-Svc · ALPN · DNS · HTTPS 리소스 레코드 · SVCB 레코드

HTTP/3 을 구현해 내보내는 서버와 도구

nginx · Caddy · curl · Envoy · 리버스 프록시 · 브라우저

HTTP/3 을 굴릴 때 걸리는 장비와 설정

로드 밸런서 · 방화벽 · 패킷 캡처 · qlog · MTU

다른 이름: HTTP/3 · h3 · HTTP version 3