Foundry
네트워크
중급
핵심

HTTP 버전 (1.1, 2, 3)

HTTP 버전별로 무엇이 달라졌고, 각 버전에서 병목이 어디에 남는지

HTTP 버전 (1.1, 2, 3)

같은 HTTP 의미를 유지하면서 전송 방식을 바꿔 온 과정

버전별 차이

항목HTTP/1.1HTTP/2HTTP/3
전송TCPTCPUDP (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 은 이어집니다.

면접에서 이렇게 나옵니다

Q.HTTP/1.1 에서 HTTP/2 로 바꾸면 무엇을 얻나요?

같은 연결에서 요청을 동시에 처리해 순서 대기가 사라지는 것이 가장 큽니다.

얻는 것내용
동시 요청자원 35개를 한 연결에서 함께 받는다
헤더 압축반복 헤더를 참조로 대체해 요청당 수백 바이트를 아낀다
연결 수 감소도메인당 6개 연결이 하나로 줄어든다
우선순위화면에 먼저 필요한 자원을 앞세울 수 있다

효과가 큰 경우가 정해져 있습니다. 작은 자원이 많을 때입니다. 아이콘과 조각난 스크립트가 수십 개인 페이지에서 눈에 띄게 빨라지고, 큰 파일 하나를 받는 경우에는 거의 차이가 없습니다.

그리고 기존 최적화 관행을 되돌려야 합니다.

관행HTTP/2 에서
파일 합치기오히려 손해. 하나만 바뀌어도 전체를 다시 받는다
도메인 분산불필요. 연결이 늘어 압축 효율이 떨어진다
이미지 스프라이트불필요

흔한 실수: HTTP/2 로 바꾸고 우회 최적화를 그대로 두는 것. 요청 수를 줄이려 합쳐 둔 것이 캐시 효율을 떨어뜨려, 기대한 만큼 빨라지지 않습니다.

Q.HTTP/3 가 TCP 대신 UDP 를 쓰는 이유는 무엇인가요?

TCP 의 순서 보장이 대기열 막힘을 만들기 때문입니다.

계층HTTP/2HTTP/3
응용의 동시 요청해결됐다해결됐다
전송의 순서 보장연결 전체가 한 줄이다스트림별로 독립적이다
패킷 하나 유실 시뒤의 모든 스트림이 기다린다그 스트림만 기다린다

TCP 는 운영체제 커널에 구현돼 있어 바꿀 수 없습니다. 그래서 UDP 위에 필요한 것(재전송, 순서, 혼잡 제어)을 새로 구현한 것이 QUIC 입니다.

부수적으로 얻은 것도 있습니다.

항목내용
연결 수립 단축전송 협상과 암호화 협상을 한 번에. 왕복이 줄어든다
연결 이전연결을 IP 가 아니라 식별자로 구분해 네트워크가 바뀌어도 이어진다
빠른 개선커널이 아니라 응용 수준이라 업데이트가 쉽다

흔한 실수: UDP 라서 신뢰성이 없다고 답하는 것. QUIC 이 재전송과 순서를 직접 구현하므로 신뢰성은 있습니다. UDP 를 고른 이유는 커널 밖에서 직접 만들 수 있는 바탕이 필요했기 때문입니다.

Q.HTTP/2 를 켰는데 오히려 느려지는 경우가 있나요?

패킷 손실이 잦은 환경에서 그렇습니다. 연결을 하나로 줄인 것이 역효과가 됩니다.

상황HTTP/1.1HTTP/2
손실 없음연결 6개로 나눠 처리한 연결에서 동시 처리. 더 빠르다
손실 잦음한 연결이 막혀도 다른 5개는 진행하나뿐인 연결이 막혀 전부 대기

이것이 HTTP/3 가 나온 이유이기도 합니다. 모바일이나 불안정한 네트워크에서 실제로 관측된 문제였습니다.

다른 원인도 있습니다.

원인내용
서버 푸시 오용이미 캐시된 자원을 밀어 넣어 대역폭을 낭비한다
우선순위 구현 차이서버와 클라이언트의 해석이 달라 중요한 자원이 늦게 온다
합쳐 둔 파일우회 최적화를 그대로 두어 캐시 효율이 떨어진다
프록시 미지원중간 장비가 HTTP/1.1 로 내려버린다

흔한 실수: 버전만 올리고 측정하지 않는 것. 사용자 환경에 따라 효과가 다르므로, 실제 사용자 지표로 전후를 비교해야 합니다.

Q.HTTP 버전과 무관하게 남는 병목은 무엇인가요?

전송 방식을 바꿔도 물리적 왕복 시간과 서버 처리 시간은 그대로입니다.

남는 병목내용
물리적 거리서울에서 미국 동부 왕복 200밀리초는 줄지 않는다
서버 처리쿼리와 렌더링 시간은 프로토콜과 무관하다
순차 의존A 응답을 받아야 B 를 부를 수 있으면 왕복이 누적된다
자원 크기5MB 이미지는 어느 버전에서도 5MB 다
렌더링 차단스크립트가 화면 그리기를 막는 것은 그대로다

세 번째가 실무에서 가장 흔합니다. HTTP/2 가 동시 요청을 해결했어도, 코드가 순차로 부르면 동시성이 생기지 않습니다.

우선순위를 정하면 이렇습니다.

순서대응
1왕복 횟수를 줄인다. 순차 호출을 병렬로
2거리를 줄인다. CDN 과 지역 배치
3자원 크기를 줄인다. 압축, 이미지 형식, 필요한 것만
4서버 처리를 줄인다. 캐시와 쿼리 개선
5프로토콜 버전을 올린다

흔한 실수: 프로토콜 업그레이드를 성능 개선의 첫 수단으로 여기는 것. 효과가 있지만 위 네 가지보다 작을 때가 많습니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

더 깊이 공부하기

읽었으면 문제로 확인해보세요

네트워크 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.