HTTP 버전 (1.1, 2, 3)
같은 HTTP 의미를 유지하면서 전송 방식을 바꿔 온 과정
버전별 차이
| 항목 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 전송 | TCP | TCP | UDP (QUIC) |
| 동시 요청 | 연결마다 하나씩 | 한 연결에서 여러 개 | 같다 |
| 헤더 | 텍스트. 매번 전체 | 압축하고 이전 값을 참조 | 같다 |
| 대기열 막힘 | 응용 계층에서 발생 | 응용에서는 해결, TCP 에는 남음 | 해결 |
| 연결 수립 | TCP 3단계 + TLS | 같다 | QUIC 이 한 번에 처리 |
HTTP/1.1 의 병목
한 연결에서 요청을 하나씩만 처리합니다. 앞 요청의 응답이 와야 다음을 보냅니다.
이미지 20개, CSS 5개, JS 10개인 페이지를 받으려면 35번의 왕복이 필요합니다. 브라우저는 이것을 완화하려고 도메인당 연결을 6개쯤 동시에 엽니다. 그래도 35개를 6개로 나눠 처리하니 6번의 순서 대기가 남습니다.
그래서 당시에는 이런 우회가 관행이었습니다.
| 우회 | 내용 |
|---|---|
| 파일 합치기 | CSS 와 JS 를 하나로 묶어 요청 수를 줄인다 |
| 이미지 스프라이트 | 여러 아이콘을 한 이미지로 합친다 |
| 도메인 분산 | 여러 서브도메인으로 나눠 연결 수 상한을 늘린다 |
| 인라인 삽입 | 작은 자원을 HTML 안에 박는다 |
HTTP/2 가 바꾼 것
한 연결에서 여러 요청을 동시에 주고받습니다. 요청을 스트림으로 나누고 프레임을 섞어 보냅니다.
| 얻는 것 | 내용 |
|---|---|
| 동시 요청 | 35개를 한 연결에서 함께 진행한다 |
| 헤더 압축 | 반복되는 헤더를 참조로 대체해 크게 줄인다 |
| 우선순위 | 중요한 자원을 먼저 받게 요청할 수 있다 |
| 서버 푸시 | 요청 전에 보낼 수 있다. 실제로는 잘 쓰이지 않아 폐기 방향 |
위의 우회들이 대부분 불필요해집니다. 오히려 파일을 합치면 하나만 바뀌어도 전체를 다시 받아야 해서 손해입니다.
HTTP/2 에 남은 문제
TCP 는 순서를 보장하므로 패킷 하나가 유실되면 그 뒤가 모두 기다립니다. 응용 계층에서는 요청을 나눴지만, TCP 계층에서는 여전히 한 줄입니다.
패킷 손실이 없는 환경에서는 문제가 되지 않습니다. 손실률이 높은 모바일 환경에서 HTTP/1.1 보다 느려지는 경우가 있었습니다.
HTTP/3 가 바꾼 것
TCP 를 버리고 UDP 위에 QUIC 을 올렸습니다. 순서 보장을 스트림 단위로 하기 때문에, 한 스트림의 손실이 다른 스트림을 막지 않습니다.
| 항목 | 내용 |
|---|---|
| 대기열 막힘 해결 | 스트림별로 독립적으로 처리한다 |
| 연결 수립 단축 | 전송과 암호화 협상을 한 번에 한다 |
| 연결 이전 | IP 가 바뀌어도 연결 식별자로 이어진다. 이동 중 유용 |
| 재전송 처리 | UDP 위에서 QUIC 이 직접 구현한다 |
세 번째가 모바일에서 체감됩니다. 와이파이에서 셀룰러로 바뀌면 TCP 는 연결이 끊기지만 QUIC 은 이어집니다.