[Chapter2] HTTP2를 향한 여정

HTTP/2 IN ACTION을 공부하며 정리한 글입니다.
틀린 부분은 지적해주시면 감사드리겠습니다 😀

HTTP/1.1의 성능 문제

웹 페이지는 정적인 정보를 제공하는 데에서 시작했다. 하지만 요즘 웹은 대화형으로 동작한다. HTTP/1.1은 애초에 단일 요청-응답 프로토콜이므로, 엄청난 리소스 증가를 염두에 두고 설계되지 않았다.

인터넷의 최대 문제 중 하나는 대기 시간이다. 대기 시간은 단일 메세지를 서버에 전송하는 데 걸리는 시간을 측정하는 것이다. 이를 개선하기 위해, HTTP/1.1에 대한 파이프라이닝을 도입하려고 시도했지만, HOL 블로킹과 같은 이슈로 웹 브라우저와 서버에서 잘 지원되지 않았다.

HOL(Head Of Line) 블로킹은 응답이 요청 순서에 따라 반환될 때, 앞선 요청의 지연으로 후속 응답까지 지연되는 현상이다.
예를 들어, 클라이언트가 이미지1과 이미지2를 순서대로 요청했을 때, 이미지1은 외부 서버에서 가져와야 하고, 이미지2는 우리 서버에서 바로 응답할 수 있는 상황이다. 응답이 요청 순서를 강제로 따라야 한다면, 이미지2는 빠르게 준비되었더라도, 이미지1의 응답이 완료될 때까지 대기하게 된다. 이로 인해 이미지2의 응답까지 지연되는 것이다.

HTTP/1.1의 성능 문제 우회적 해결 방법

HTTP/1.1은 사실상 동기적으로 동작하기 때문에, 현재 요청이 완료될 때까지는 다른 HTTP 요청으로 옮겨갈 수 없다. 웹 페이지가 복잡해지고, 렌더링에 더 많은 리소스가 필요해지면서, 느림은 문제가 되기 시작했다. 이를 우회적으로 해결하기 위한, 팁과 트릭이 존재한다.

도메인 샤딩

HTTP/1.1은 한 도메인당 동시 연결 수가 6개로 제한되어 있다. 기본적으로 백엔드 서버에서 모든 리소스를 받아올텐데, 도메인 샤딩을 활용하면, CSS, JS와 같은 정적 자산을 하위(서브) 도메인으로 분산하면, 각 도메인마다 별도의 연결 제한이 적용되어 더 많은 요청을 동시에 처리할 수 있게 된다.

또한, 파이프라이닝과 다르게 HOL 블로킹이 발생하지 않는다. 파이프라이닝의 경우, 한 연결을 통해, 여러 요청을 순차적으로 보내는 것이지만, 도메인 샤딩을 이용하면, 여러 도메인에 분산해 요청을 보내기 때문에, 각각 별도의 연결을 사용한다.

하지만 도메인 샤딩은 여러 HTTP 연결을 만드는 것이므로, 클라이언트나 서버에 부하를 주게 된다. 여러 연결을 사용할 경우, TCP의 느린 시작이 성능 저하로 이끌게 된다. 이는, TCP가 네트워크 혼잡을 방지하기 위해, 초기 전송 속도를 작게 시작해서, 성공적인 응답을 받을 때마다 전송 속도를 지수적으로 증가시키는 것이다. 때문에 여러 HTTP 연결이 생성되면 각 연결이 독립적으로 느린 시작을 거치므로 데이터 전송 속도가 전체적으로 느려지는 문제가 발생할 수 있다.

이런 우회책은 자체의 비효율성을 만들어내지만, 웹 사이트가 크기와 복잡성 두 가지 면에서 모두 계속 성장하기 때문에, 우회책도 한계가 존재한다.

SPDY(Speedy)

SPDY의 목적은 HTTP/1.1의 성능 한계를 해결하는 것이었다. 이런 한계를 다루기 위해 다음과 같은 큰 중요 개념을 도입했다.

  • 다중화된 스트림
    • 요청 및 응답은 단일 TCP 연결을 사용
    • 분리된 스트림들의 그룹으로 나눠진 인터리브된 패킷 사용
  • 요청 우선 순위 지정
    • 모든 요청을 동시에 보내기 위해 요청의 우선 순위 개념 도입
  • HTTP 헤더 압축
    • HTTP 본문은 압축해왔지만, 헤더도 압축 가능하도록 도입

SPDY는 이후 HTTP/2 표준화 과정에서 주요 기능들이 반영되었다.

HTTP/2

HTTP/2는 위에서 본 것과 같이, HTTP가 갖고 있는 본질적인 성능적 이슈를 타개하고자 새로운 개념을 도입해 나온 것이다. 하지만 HTTP/2를 사용한다고 항상 성능이 향상되는 것은 아니다.

HTTP/2 download test

Performance 테스트 페이지의 결과에 의하면, HTTP, HTTPS의 경우 360개의 이미지 리소스를 받아올 때, 최대 16.557s가 소요되는 것을 볼 수 있었지만, HTTP/2의 경우 1.939s가 소요된 것을 볼 수 있다.

시간 자체는 HTTP/2가 훨씬 빠르지만, 실제로 각각의 리소스를 받아오는 시간은 HTTP/1에 비해 큰 차이가 없다. HTTP/1은 동시에 여섯 요청에 대한 자연스러운 큐 매커니즘을 생성하지만, HTTP/2는 스트림을 사용한 단일 연결을 사용한다. 때문에, 동시에 많은 요청을 보내면, 사용 가능한 리소스를 공유하고, 다운로드하는 시간이 더 오래걸릴 수 있다.

즉, HTTP/2를 사용한다고해서 무조건 성능이 개선되지 않는 것이다. 이를 적용하기 전에는, HTTP/2를 적용했을 때의 성능 기대치를 설정하는 것이 좋다.

정리

HTTP/1은 요청-응답 프로토콜로, 하나의 요청을 보내면, 그에 대한 응답을 받을 때까지 기다리기 때문에, 여러 리소스를 가져올 때 성능 문제가 발생한다. 이를 해결하기 위한 우회 방법이 있지만, 자체의 문제점이 있다. SPDY는 이러한 성능 문제를 해결하고자 설계되었고, HTTP/2가 이에 대한 표준화된 버전인 것이다. 하지만, HTTP/2를 사용한다고 100% 성능이 개선되는 것은 아니다.

댓글남기기