Tech

모두를 위한 Http2

http2에 대해 소개합니다.

2020-09-29 Kei Jeon

반갑습니다. 숨고 프론트엔드 챕터를 리딩하는 Kei 입니다.

저희 Tech팀 내부에서 기술블로그를 남겨보자고 논의된게 어느덧 1년이 넘은것 같은데 드디어 첫 포스팅을 남깁니다. 무척 기쁘고 기대가 됩니다.

이 글을 시작으로 숨고라는 서비스, 조직이 아직 보여주지 못한 숨고의 여러 기술적인 고민들을 계속해서 기록하면 좋겠습니다.

주제

첫번째 포스팅의 주제는 Http2 입니다.

굉장히 중요한 기술이지만 당장은 필요 없고 굳이 알기위해 귀찮은 노력을 하지 않는다면 얻을 수 없는 계륵(鷄肋)과 같은 기술이지요.

마침 지난달 사내 세미나에서 발표하여 정리를 해봤기에 부담없이 기록할 수 있을것 같네요.

무엇인가

Http2를 한마디로 정의한다면 “괜찮은 기술을 때려넣은 만든 Http1 보다 빠른 녀석”이라고 정의할 수 있을것 같습니다.

하지만 이는 현상적인 설명일 뿐이고 Http2는 여러가지 정의를 가질 수 있습니다.

  • 25년산 Http1의 Next Generation
  • 구글이 만든 SPDY 프로토콜의 Official Stable Version
  • 네트워크 복수 요청에 대한 최적화가 이루어진 Http

이처럼 관점에 따라서 여러가지 정의가 있을 수 있지만 이 포스팅에선 마지막 성능적인 관점에서의 Http2를 다뤄볼까 합니다.

Http 1의 문제

모든 애플리케이션이 다음 릴리즈를 출시하는 이유가 있듯 Http2도 기존 버전의 Http가 해결할 수 없는 이러 저러한 문제를 해결하기위해 고안되었습니다.

시간이 지날 수록 서버들은 큰 용량의 리소스를 제공하고 네트워크의 규모와 성능이 나날이 좋아지는 만큼 Http1은 이전에 없던 다음과 같은 문제를 직면 했습니다.

  • 요청마다 필요한 무거운 Tcp Connection
  • 첫번째 패킷의 Resolve를 기다리는 Head Of Line Blocking
  • 무거운 헤더 사이즈 Heavy Header

Http1은 태생적으로봐도 표준 채택을위해 의도적으로 단순하게 만들었고 성능에 대해선 크게 논의되지 않았다는게 HPBN에서 확인됩니다.

프론트엔드 엔지니어들은 이러한 근본적인 문제를 끌어안고 이미지 스프라이트, 도메인샤딩, 웹팩 번들링등 눈물 나는 최적화를 진행했던 기억이 저 역시도 있습니다.

Http1 vs Http2

Http2의 동작은 Http1과 비교했을때 다음과 같이 묘사될 수 있는데 모르는 사람이 봐도 Http1은 요청-응답이 직렬로 이루어지고 Http2는 비교적 병렬로 이루어지는것을 확인할 수 있습니다.

이번엔 Http2로 전달하는 패킷의 레이아웃을 봅시다.

기본적으로 Network, Transport, Session 레이어에선 Http1과 Http2의 차이가 없습니다. 이 둘을 나누는것은 단지 Application 레이어의 차이라고 볼 수 있지요.

Http1에서 문자열과 개행으로 구분된 Header, Body의 데이터가 Http2에선 Binary Framing이라는 압축된 스트림으로 대체됩니다. 이런 스트림들은 이후에 설명할 여러 기술을 통해 다중화되어 병렬로 전달됩니다.

다중화 (multiplexing)

다중화는 네트워크 용어로 여러 데이터를 하나의 결합된 데이터로 보낸다는 의미를 내포하고 있습니다.

Http2 관점에서 볼때 위에서 설명한 Binary Framing 계층의 여러 Headers, Data 프레임이 하나의 TCP 연결에 결합되어 전송됩니다.

Http1에선 개별 Frame 마다 비싼 비용의 TCP 연결이 생성 되었으니 주목할만한 개선이라고 볼 수 있지요. 이를 자세히보면 다음과 같은 절차로 전송됩니다.

  • Http 메시지를 독립된 프레임으로 세분화
  • 이 프레임을 우선순위에 맞게 TCP 연결에 끼워넣는다 (인터리빙)
  • 수신 채널에서 이를 프레임을 재 조립하여 Http 메시지로 가공

이렇게 프레임을 다중화하여 TCP 연결을 최소화하는것이 Http2 성능 최적화에 핵심이라고 볼 수 있습니다.

서버 푸시

다중화와 더불어 Http2에서 주목할만한 개선은 서버 푸시입니다.

단일 요청에 대한 복수 응답을 의미하는 개념인데 이는 기존의 비슷한 동작을 구현하기위해 필요했던 비싼 비용의 소켓, 폴링, 스트리밍과 같은 기술들과 구분됩니다.

단지 한번의 요청이면 됩니다.

서버는 어떤 리소스가 클라이언트에 필요한지 이미 알고 있습니다.

이러한 개념을 이용해 한꺼번에 리소스를 제공한다면 불필요한 TCP 연결을 최소화할 수 있지요.

또한 원하지 않는 리소스를 클라이언트가 제어할 수 있도록 SETTINGS 프레임을 정의할 수 있습니다.

(참고: https://github.com/spdy-http2/node-spdy#push-streams)

HPACK 압축

HPACK 압축은 이전에 없던 새로운 압축 알고리즘이 아니라 Http2에서 주고받을 헤더의 사이즈를 줄이기 위해 명명된 기술 이름입니다.

HPACK은 크게 Huffman Code를 이용한 무손실 압축, Header Indexing 등의 최적화를 포함하고 있습니다.

Huffman Code 무손실 압축은 위키피디아의 설명으로 대체하고 Header Indexing은 다음과 같은 원리로 이루어집니다.

  • 이전에 표시된 헤더의 색인 목록을 클라이언트와 서버가 유지
  • 새로 추가된 헤더에 대해서만 압축되어 포함

결과

위 세가지 개선 뿐 아니라 Stream Prioritization, One Connection Per Origin, Flow Control 등의 개선도 있습니다. 운용중인 제품에 Http2로의 전환을 검토한다면 한번씩 읽어봐야할 녀석들입니다.

여러 아티클조사한 자료들에 따르면 Http1 대비 Http2의 성능수준이 리소스 구조에 따라 최소 14% ~ 40% 정도의 개선을 말하고 있습니다. 전체 리소스의 규모가 크고 잘게 쪼개어 제공 될수록 더 높은 개선을 얻을 수 있지요. 이는 전반적으로 규모가 커지는 애플리케이션의 방향에 더욱더 필요한 기술이라고 말할 수 있습니다.

Http2는 확실히 Http1보다 좋고 빠릅니다. 또한 대부분의 브라우저와 웹서버가 안정화된 기능(Stable Feature)으로 이를 지원하고 있습니다. 이미 많은 서비스가 Http2로의 전환을 이루어냈고 성능 개선을 체감하고 있습니다. 이에 경각심을 느끼며 숨고 역시 완전한 Http2로의 전환을 하나씩 진행하고 있습니다.



관련해서 리서치를 진행할수록 해볼만한 가치가 있는 개선이라고 생각이 들었습니다. 성능을 중요한 관점으로 보신다면 더욱이 그렇습니다.

Kei Jeon Soomgo Front-end Engineer
숨고의 성장을 위해 열심히 고민하며 노력하고 있습니다.