❒ Description
이번에는 HTTP/2.0이 왜 등장했고, 이전 버전과 어떤 차이를 가지는지 공부하자!
❒ 등장 배경
HTTP/1.1의 메시지 포맷은 구현의 단순성과 접근성에 주안점을 두고 최적화되었기 때문에 어느정도 성능은
희생시킬 수 밖에 없었다. HTTP/1.1에서 HTTP 트랜잭션은 요청과 응답으로 심플하게 구성되어있는데,
응답을 받아야만 다음 요청을 할 수 있기 때문에 회전 지연(RTT: Round Trip Time)을 피할 수 없다는 단점이 있다.
물론 이 문제를 해결하기 위해서 병렬 커넥션, 파이프라인 커넥션 기술이 등장했지만, 각각 제약들도 있었고
근본적인 문제가 해결이 되지 못했다. 여기서 근본적인 문제라 함은, 한 번에 하나의 요청만 처리할 수 있다는
구조적 한계를 말한다.
이렇게 근본적인 문제를 해결하고자 다양한 프로토콜들이 등장했는데, 2009년 구글은 SPDY 프로토콜을 발표한다.
SPDY 프로토콜은 다음의 특징을 가지고 있다.
- 헤더를 압축하여 대역폭(Bandwidth)을 절약
- 하나의 TCP 커넥션에 여러 요청을 동시에 보내 RTT 단축
- 서버가 능동적으로 리소스를 push하는 기능
- Stream에 대한 우선 순위 부여와, 흐름제어 기능
결국 HTTP/2.0 은 SPDY를 기반으로 설계되었다.
❒ Binary Framing Layer
HTTP/1.1의 메시지는 헤더와 본문이 ASCII 텍스트로 표현되며, 비교적 비구조화된 형식으로 구성된다.
하지만 HTTP/2.0의 모든 메시지는 Binary-Frame에 담겨 전송된다.
프레임은 8byte 크기의 헤더와, 최대 16838byte 크기의 페이로드로 구성되어 있다.
위 그림에서 보면 알 수 있듯 HTTP/2.0에서는 메시지를 프레임화한 것을 확인할 수 있다.
Binary-framing layer는 요청/응답을 바이너리로 변환하고 이를 작은 덩어리(프레임)로 나누어 양방향 스트림을 형성한다.
Binary-framing layer 덕분에 HTTP/2.0은 열린 상태로 유지되는 단일 TCP 연결을 사용한다.
❒ Frame, Message, Stream
1. Frame
프레임은 HTTP/2.0 통신의 가장 작은 단위이다. 프레임은 HTTP 헤더 또는 페이로드와 같은 특정 유형의
데이터를 전달한다.
2. Message
메세지는 여러 개의 프레임으로 구성되며 하나의 요청(Request) 또는 응답(Response)을 의미한다.
HTTP/1.1에서의 요청/응답과 개념적으로 동일하다.
3. Stream
스트림은 HTTP/2에서 클라이언트와 서버 간의 프레임 교환이 이루어지는 논리적 연결이다.
하나의 TCP 커넥션 내에서 여러 개의 스트림이 동시에 존재할 수 있다. 따라서 RTT 문제를
해결할 수 있게 됐다. 뿐만 아니라 스트림은 우선순위도 가질 수 있는데, 우선순위가 100% 보장되지는 않는다.
서버와 클라이언트는 Stream을 상대방과 협상 없이 일방적으로 맺을 수 있는데,
이는 TCP 커넥션을 맺을 때 3-way handshake를 하느라 시간을 낭비하지 않기 위함이다.
HTTP/2 커넥션에 한 번 사용된 스트림 식별자는 다시 사용할 수 없다. 커넥션을 오래 사용하다 보면
스트림에 할당할 수 있는 식별자가 고갈되기도 하는데, 이런 경우에는 커넥션을 다시 맺으면 된다.
모든 스트림은 31비트의 무부호 정수로 된 고유한 식별자를 갖는다.
스트림이 클라이언트에 의해 초기화되었다면 이 식별자는 반드시 홀수여야 하며 서버라면 짝수여야 한다.
또한 새로 만들어진 스트림의 식별자는 이전에 만들어졌거나 예약된 스트림들의 식별자 보다 커야 한다.
이 규칙을 어기는 식별자를 받았다면 에러가 코드가 PROTOCOL_ERROR인 커넥션 에러로 응답해야 한다.
정리해보면, HTTP 요청을 여러개의 Frame으로 나누고, 이 Frame들이 모여 요청/응답 Message가 되고,
Message는 특정 Stream에 속하게 되고, 여러개의 Stream은 하나의 TCP 커넥션에 속하게 되는 구조다.
❒ Multiplexing
1. Multiplexing이란?
Multiplexing이란 여러 개의 스트림을 사용하여 송수신하는 것을 의미한다. 이를 통해 특정 스트림의 패킷이 손실되었다고
하더라도 해당 스트림에만 영향을 미치고 나머지 스트림은 문제없이 동작할 수 있다.
위 그림은 하나의 연결 내 여러 스트림을 캡쳐한 모습인데, 병렬적인 스트림들을 통해 데이터를 서빙하고 있다.
또한 스트림 내의 데이터들도 쪼개져있음을 확인할 수 있다.
2. Multiplexing을 사용함으로써 얻는 이점
1. 동시성 증가
멀티플렉싱을 통해 단일 TCP 연결에서 여러 개의 요청과 응답이 동시에 이루어질 수 있게된다.
이는 HTTP/1.x에서닁 문제점이였던 HOL Blocking 문제를 해결하여, 여러 리소스를 병렬로 전송할 수 있게 한다.
2. 성능 향상
여러 개의 요청이 병렬로 처리되므로, 페이지 로딩 속도가 빨라진다.
3. 연결 효율성
HTTP/1.1에서는 각 요청마다 새로운 TCP 연결을 생성하거나, 지속적인 연결을 유지해야 했지만, HTTP/2.0에서는
단일 TCP 커넥션 내에서 다수의 요청과 응답을 관리할 수 있어, 불필요한 연결 생성과 관리 비용을 줄일 수 있다.
4. 대역폭 최적화
여유 대역폭을 최대한 활용하도록 하여, 네트워크 대역폭을 보다 효율적으로 사용한다.
이를 통해 네트워크 혼잡을 줄이고, 전체적인 성능을 향상시킬 수 있다.
예를 들어 네트워크의 대역폭이 100이라고 가정하면, 기존에는 용량이 30인 데이터가 전송될 때 70은 놀고있었지만,
멀티플렉싱을 사용하는 HTTP/2.0의 경우에는 데이터 크기가 30, 20, 50 인 패킷이 한 번에 전송될 수 있다는 것.
5. 우선순위 지정
HTTP/2.0에서는 각 스트림에 우선순위를 지정할 수 있어, 중요한 리소스를 먼저 전송하도록 설정할 수 있다.
이는 사용자의 경험을 더욱 향상시키는 데 기여한다.
❒ Flow Control
위에서 Multiplexing 덕분에 HOL Blocking을 해결할 수 있다고 했는데, 어떻게 해결되는 것일까?
그 비밀은 흐름제어(flow control)에 있다.
HTTP/2.0은 WINDOW_UPDATE 프레임을 이용한 흐름제어(flow control)을 통해 스트림들이 서로
간섭해서 문제가 생기는 것을 막아주는데, 어떻게 흐름을 제어하는지 그 과정을 알아보자.
1. 초기 상태
클라이언트와 서버는 각각 스트림(Stream)과 연결(Connection)당 65,535 바이트의 초기 윈도우 크기를 가지고 있다.
이 윈도우 크기는 각 스트림이나 연결에서 수신할 수 있는 데이터 양을 의미한다.
2. 첫 번째 데이터 전송
클라이언트가 서버로 16,000 바이트의 데이터를 전송한다. 이 전송으로 인해 클라이언트의 스트림과 연결에 대한
윈도우 크기가 65,535 바이트에서 49,535 바이트로 감소한다. 즉, 현재 스트림과 연결에서 수신할 수 있는
데이터 양이 줄어든 것이다.
3. 두 번째 데이터 전송
클라이언트는 다시 16,000 바이트의 데이터를 서버로 전송합니다.
이로 인해 클라이언트의 스트림과 연결에 대한 윈도우 크기가 다시 줄어들어 49,535 바이트에서 33,535 바이트가 된다.
4. 서버에서 윈도우 업데이트
서버는 수신한 데이터를 처리한 후, 클라이언트에게 WINDOW_UPDATE 프레임을 보내 스트림과 연결의 윈도우 크기를
각각 32,000 바이트만큼 증가시킨다. 이 업데이트로 클라이언트의 스트림과 연결의 윈도우 크기는 다시 65,535 바이트가
되어 원래 크기로 복구된다.
흐름 제어는 클라이언트와 서버가 서로 데이터를 주고받을 때, 수신할 수 있는 데이터 양(윈도우 크기)을 관리하는 과정이다.
클라이언트가 데이터를 전송할 때마다 윈도우 크기가 감소하고, 서버가 데이터를 처리한 후 윈도우 크기를 업데이트하여
클라이언트가 더 많은 데이터를 전송할 수 있게 한다.
이를 통해 네트워크에서의 데이터 흐름이 원활하게 유지되고, 송신자가 너무 많은 데이터를 한꺼번에 보내는 것을 방지할 수
있다. 이 과정은 HTTP/2.0에서 멀티플렉싱의 효율성을 높이면서도 네트워크의 안정성을 유지하는 데 중요한 역할을 한다.
❒ Header Compression
HTTP/1.1에서 무거운 헤더는 아무런 압축 없이 그대로 전송되었다.
수많은 요청을 보낼 때 무거운 헤더로 인해 회전 지연과 대역폭 양쪽 모두에 영향을 끼쳤다.
이 부분을 개선하기 위해 HTTP/2.0에서는 HTTP 메시지의 헤더를 압축하여 전송한다.
만일 헤더에 중복값이 존재하는 경우, Static/Dynamin 테이블 개념을 사용하여 중복 헤더를 검출하고
중복된 헤더는 index값만 전송하고 중복되지 않은 헤더 정보의 값은 호포만 코딩 압축 알고리즘을
사용하는 HPACK 압축 방식으로 압축하여 전송한다.
💬 허프만 코딩이란?
허프만 코딩은 문자열을 문자 단위로 쪼개 빈도수를 세어 빈도가 높은 정보는 적은 비트 수를
사용하여 표현하고, 빈도가 낮은 정보는 비트 수를 많이 사용하여 표현해서 전체 데이터의
표현에 필요한 비트양을 줄이는 원리.
❒ Server Push
HTTP/2.0은 서버가 하나의 요청에 대해 응답으로 여러 개의 리소스를 보낼 수 있도록 해준다.
예를 들어, HTML 문서를 요청 받은 서버는 그 HTML 문서가 링크하고 있는 이미지, CSS 파일, 자바스크립트 파일
등의 리소스를 클라이언트에게 푸시할 수 있을 것이다. 이는 클라이언트가 HTML 문서를 파싱해서 필요한 리소스를
다시 요청하여 발생하게 되는 트래픽과 RTT를 줄여준다.
리소스를 푸시하려는 서버는 먼저 클라이언트에게 자원을 푸시할 것임을 PUSH_PROMISE 프레임을 보내어 미리
알려줘야 한다. 이렇게 하는 이유는 서버가 푸시하려고 하는 자원을 클라이언트가 별도로 또 요청하게 되는 상황을
피하기 위함이다.
❒ 문제점
1. 여전한 RTT
여전히 TCP를 사용하기 때문에 Handshake의 RTT로 인한 지연이 발생한다.
2. TCP - HOL Blocking
애플리케이션 계층의 HOL Blocking을 해결한 것이지, 전송 계층의 HOL Blocking을 해결한 것은 아니다.
TCP는 패킷이 유실되거나 오류가 있을 때 재전송 하는데, 이 과정에 HOL Blocking이 발생한다.
3. Intermediary Encapsulation Attacks(중개자 캡슐화 공격)
HTTP 2.0은 헤더 필드의 이름과 값을 바이너리로 인코딩한다. 이를 다르게 말하면 HTTP 2.0 이 헤더 필드로
어떤 문자열이든 사용할 수 있게 해준다는 뜻이다.
그래서 이를 악용하면 HTTP 2.0 메시지를 중간의 Proxy 서버가 HTTP 1.1 메시지로 변환할 때 메시지를 불법
위조할수 있다는 위험성이 있다. 다행히 거꾸로 HTTP/1.1 메시지를 HTTP/2.0 메시지로 번역하는 과정에서는
이런 문제가 발생하지 않는다.
4. 긴 커넥션 유지로 인한 개인정보 누출 우려
HTTP 2.0은 기본적으로 성능을 위해 클라이언트와 서버 사이의 커넥션을 오래 유지하는 것을 염두에 두고 있다.
하지만 이것은 개인 정보의 유출에 악용될 가능성이 있다. 이는 HTTP/1.1에서의 Keep-Alive도 가지고 있는 문제
이기도 하다.
❒ 예상 면접 질문
1. HTTP 2.0은 왜 나왔나요?
HTTP/2.0의 등장 배경은 주로 HTTP/1.1의 성능 한계를 극복하기 위해서입니다. HTTP/1.1은 여러 요청을
순차적으로 처리하기 때문에, 네트워크 지연과 같은 문제로 인해 성능 저하가 발생할 수 있습니다.
이러한 문제를 해결하기 위해 HTTP/2.0은 멀티플렉싱, 헤더 압축, 서버 푸시 등의 기능을 도입하여,
웹 페이지 로딩 속도와 네트워크 효율성을 크게 개선했습니다.
HTTP/2.0은 이러한 성능 향상을 통해 사용자 경험을 향상시키는 것을 목표로 등장했습니다.
2. HTTP/2.0과 HTTP/1.1의 메시지 구조에는 어떤 차이점이 있나요?
HTTP/2.0의 Binary Framing Layer는 HTTP/1.1과의 중요한 차이점 중 하나입니다.
HTTP/1.1에서는 텍스트 기반의 프로토콜을 사용하여 요청과 응답을 처리하지만, HTTP/2.0에서는 바이너리 프레이밍 레이어를
도입해 데이터를 이진 형식으로 전송합니다. 이를 통해 더 효율적인 데이터 전송이 가능해지며, HTTP 헤더와 본문이 프레임이라는 작은 조각으로 나누어져 전송되므로, 네트워크 성능이 개선됩니다. 이 과정에서 각 프레임은 특정 스트림에 할당되어 멀티플렉싱이 가능해집니다.
3. HTTP/2.0에서 Multiplexing이란 무엇이며, 어떤 이점을 제공하나요?
Multiplexing은 HTTP/2.0에서 하나의 TCP 연결을 통해 여러 요청과 응답을 동시에 주고받을 수 있게 하는 기술입니다.
이는 HTTP/1.1에서의 요청-응답 순서 때문에 발생하는 지연 문제를 해결합니다. Multiplexing의 주요 이점은 네트워크 효율성을
높이고, 페이지 로드 속도를 향상시키며, HOL (Head-of-Line) Blocking 문제를 완화하는 것입니다.
3-1. 멀티플렉싱 덕분에 HOL Blocking을 해결할 수 있다고 했는데, 어떻게 해결하는 건가요?
HTTP 2.0은 WINDOW_UPDATE 프레임을 이용한 흐름제어(flow-control)를 통해 해결합니다.
이는 수신자가 처리할 수 있는 데이터의 양을 결정하여, 네트워크 혼잡을 방지하고 시스템 자원을 효율적으로
관리할 수 있게 합니다. 각 스트림마다 독립적인 윈도우 크기를 설정할 수 있어, 데이터가 과도하게 전송되는
것을 방지합니다.
4. 그럼 HTTP 2.0 에는 문제가 없나요?
여전히 몇 가지 문제가 있습니다.
1. 여전한 RTT
TCP를 사용하면 어쩔 수 없이 handshake 과정이 발생하는데 이때 지연이 발생하게 됩니다.
2. TCP의 HOL Blocking
TCP는 패킷이 유실되거나 오류가 있을 때 재전송하는데, 이 과정에서 HOL Blocking이 발생합니다.
3. 중개자 캡슐화 공격
HTTP 2.0은 헤더 필드에 어떤 문자열이든 사용 가능합니다.
그래서 이를 악용하면 HTTP 2.0 메시지를 중간의 Proxy 서버가 HTTP 1.1 메시지로 변화할 때
메시지를 불법 위조할 수 있다는 위험성이 있습니다.
4. 개인정보 유출
이 문제는 HTTP 1.1도 가지고 있는 문제인데요. 커넥션을 오래 지속하다 보면 개인정보 유출의 위험성이 있습니다.
'CS > Network' 카테고리의 다른 글
HTTP 3.0 (0) | 2024.08.23 |
---|---|
SSL/TLS Handshake (0) | 2024.08.22 |
HTTP Connection Management (0) | 2024.08.14 |
TCP 제대로 이해하기 (0) | 2024.08.14 |
3xx - Redirection Status Code (0) | 2024.08.10 |