와탭 블로그

전체보기

HTTP/2 알아보기 - 1편

2019년 7월 29일

blog_38_main

최근 많은 웹서비스들이 HTTP/2로 이루어지고 있습니다. 와탭 모니터링 SaaS 서비스 또한 AWS의 ALB를 통해 HTTP/2 프로토콜로 서비스되고 있는데요. HTTP/2는 기존의 HTTP/1.x에 비해 성능이 좋습니다.HTTP/2는 기존의 HTTP/1.x 프로토콜의 모든 핵심 개념들을 그대로 유지하면서 큰 성능 개선을 보여줍니다. 그래서 지금 서비스 중인 웹서비스가 HTTP/1.1로 통신되고 있다면 HTTP/2에 필요한 옵션과 기능들을 추가하는 것 만으로 많은 성능 개선을 볼 수 있습니다. 그럼 HTTP/2의 핵심 내용을 간략히 알아보고 실제 톰캣으로 HTTP/2 통신을 적용해 보겠습니다.

HTTP/1.x

HTTP/2(이하 H2)와 HTTP/1.x(이하 H1)와의 가장 큰 변화는 속도 향상입니다. H1의 성능 저하 부분과 비효율적인 것들을 개선되어 탄생한 것이 H2라고 생각하면 쉽습니다. H1에서 문제가 되는 부분을 보고 H2에서는 어떻게 해결하였는지 보겠습니다.

HTTP/1.1

HTTP는 TCP 연결 기반 위에서 동작하는 프로토콜입니다. 신뢰성 확보를 위해 연결을 맺고 끊는 데 있어서 핸드 셰이크가 이루어집니다. 거기에다 HTTP는 비연결성 프로토콜이기 때문에 한 번 연결로 한 번의 요청과 응답을 하고 응답이 끝나면 연결을 끊어 버립니다. 연결을 맺고 끊을 때마다 핸드 셰이크를 하기 때문에 비연결성 프로토콜에선 오버헤드가 생깁니다. 특히 요즘 웹서비스들은 하이퍼 텍스트라기보다는 많은 정적 데이터로 이루어진 하이퍼 미디어로 발전했기 때문에 오버헤드가 커질 수 있습니다. 그래서 HTTP/1.1에서 Keep-alive 기능이 추가되어 한 번 맺어졌던 연결을 끊지 않고 지속적으로 유지하여 불필요한 핸드 셰이크를 줄여 성능을 개선할 수 있습니다. 이런 식으로 웹페이지가 예전의 텍스트 위주와는 다르게 점점 미디어들이 추가되고 상태(쿠키, 세션 등)를 유지하려는 기술들이 요구되다 보니 성능 개선이 반드시 필요하게 되었고 이를 위해 부가적인 기능들이 추가되다 H2까지 발전하게 된 것입니다.

HTTP/1.1에서 성능 개선을 위해 파이프라이닝이라는 기술이 도입되었습니다. 하나의 커넥션에서 한 번에 순차적인 여러 요청을 연속적으로 하고 그 순서에 맞춰 응답을 받는 방식으로 지연 시간을 줄이는 방법입니다. 순차적으로 데이터를 요청하고 받아야 하다 보니 먼저 받은 요청이 끝나지 않으면 그 뒤에 있는 요청의 처리가 아무리 빨리 끝나도 먼저 온 요청이 끝날 때까지 기다려야 합니다. 이를 HTTP의 HOL(Head Of Line) Blocking 문제라고 하고 파이프라이닝의 큰 문제입니다. 그래서 모던 브라우저들은 대부분은 파이프라이닝을 사용하지 못하도록 막아 놓았습니다. 그래서 H1으로 통신할 때 클라이언트(브라우저)가 요청을 병렬로 하기 위해서 6-8개(브라우저마다 다름)의 커넥션을 이용해 데이터를 가져오는 방식으로 성능을 개선하고 있습니다.

http_1_1 HTTP/1.1 파이프라이닝
http_1_2 크롬 개발자 도구로 확인한 HTTP/1.1의 데이터 요청 응답 과정에서 6개의 커넥션 ID가 사용됐다.
HTTP/2의 바이너리 프레임과 멀티플렉싱

H2의 핵심은 바이너리 프레이밍 계층을 사용해 요청과 응답의 멀티플렉싱을 지원한다는 것입니다. HTTP 메시지를 바이너리 형태의 프레임으로 나누고 이를 전송 후 받은 쪽에서 다시 조립합니다. 요청과 응답이 동시에 이루어지니 하나의 연결에 여러 요청과 응답이 뒤섞여 있습니다. 프레이밍 작업은 서버와 클라이언트(브라우저)에서 해주기 때문에 큰 변경사항을 고려하지 않아도 됩니다. 바이너리 프레이밍과 멀티플렉싱을 이용해 여러 개의 연결 없이 병렬 처리도 할 수 있고 파이프라이닝과 달리 HOL문제를 해결한 것입니다.

또한 그 외에도 요청 우선순위를 지정할 수 있고 헤더를 압축하여 헤더 오버헤드를 줄이고 클라이언트가 명시적 요청을 하지 않아도 필요한 리소스를 미리 푸시하여 응 답 시간을 줄이는 서버 푸시 기능이 추가되었습니다. H2의 발전 과정과 목표, 자세한 기술적인 내용은 구글 개발자 페이지에서 볼 수 있습니다.

http_2 바이너리 프레이밍 계층 출처 : 구글
    용어 설명
  • 스트림 : 구성된 연결 내에서 전달되는 바이트의 양방향 흐름이며, 하나 이상의 메시지가 전달될 수 있습니다.
  • 메시지 : 논리적 요청 또는 응답 메시지에 매핑되는 프레임의 전체 시퀀스입니다.
  • 프레임 : HTTP/2에서 통신의 최소 단위이며 각 최소 단위에는 하나의 프레임 헤더가 포함됩니다. 이 프레임 헤더는 최소한으로 프레임이 속하는 스트림을 식별합니다.

이제 실제 톰캣을 이용해서 H2를 위한 설정을 해보고 간단한 WAS를 만들어HTTP/1.1과 HTTP/2의 페이지 로드 시간을 비교해보겠습니다.

톰캣으로 H2를 설정하여 H1과 단순 비교 해보기

톰캣은 8.5 버전 이상부터 H2를 지원합니다. 단 8.5에서는 APR(Tomcat Native)를 설치해야 H2가 작동합니다. 또한 H2로 통신하기 위해서는 TLS가 적용되어야 작동합니다. TLS 적용은 H2의 표준은 아니지만 대부분의 브라우저에서 TLS 설정이 안 되어 있으면 H2로 통신이 불가능하도록 되어 있습니다.

톰캣 8.5 버전에서 HTTPS와 APR을 설정하고 와탭 로고를 225개의 이미지로 나누어 이를 전송하는 WAS를 만들었습니다. 그리고 톰캣 서버는 로컬 VM에서 설치되어 있기 때문에 육안으로도 성능 차이를 가늠할 수 있게 하기위해 강제로 네트워크 쓰로틀링을 걸어 레이턴시를 30ms로 설정하였고고 브라우저 캐싱 기능을 껐습니다. HTTP/2를 위한 톰캣에서의 Tomcat Native 설치와 아래와 같은 커넥터 설정이 전부입니다. 그럼 브라우저에서 H2를 지원하면 H2로 통신이 되고 그렇지 않을 경우 H1으로 통신이 됩니다.

http_2_tomcat 톰캣 HTTP/2 설정 커넥터 설정
http_2 HTTPS/1.1 이미지 로드 시간
http_2 HTTP/2 이미지 로드 시간

위 이미지를 보면 H2가 같은 조건에서 2배에 가까운 성능 개선을 보여주고 있습니다. 이 성능 차이는 레이턴시가 나쁜 환경에서 더 명확해집니다. 또한 전체 전송 데이터 크기도 줄어드니 네트워크 부하도 줄어듭니다. H2를 위한 설정만 해준다면 전체 성능을 쉽게 개선할 수 있습니다.

그럼 다음 글에서는 여기서 만든 톰캣 WAS를 이용해 패킷을 수집하여 헤더 프레임과 데이터 프레임이 어떻게 주고 받아지는지 조금 더 알아보겠습니다.

참고
https://developers.google.com/web/fundamentals/performance/http2/ https://hpbn.co/http1x/#using-multiple-tcp-connections https://tools.ietf.org/html/rfc7540
whatap_taehoon_kim
김태훈(taehoon@whatap.io)
Pre-sales Consulting TeamPre-sales Engineer
<  이전 글

다음 글  >

최신글