Search
Duplicate
📒

[Network Study] 02-5. HTTP/2

상태
완료
수업
Network Study
주제
HTTP
4 more properties
참고

HTTP/2 신택스

NOTE
HTTP/1.1에서 많은 기능이 추가되었고 성능도 좋아졌지만, 브라우저에서의 요청의 수나 콘텐츠가 무거워졌습니다. 구글은 이에 한계를 느끼고 SPDY라는 프로젝트를 진행했고, SPDY를 토대로 HTTP/2.0이 시작되었습니다.
HTTP/1.1의 성능 문제는 대표적으로 다음과 같은 이슈들이 있었습니다.
Head-of-Line Blocking(HOL): HTTP/1.1에서는 1대1 요청/응답만 가능해서 다수의 리소스를 요청할 경우 앞선 요청이 완료될 때까지 대기해야 했습니다.
연결 하나의 요청: 각 TCP 연결은 한 번에 하나의 요청/응답이 가능했으므로 병렬로 다운로드 하기 위해서는 여러 TCP 연결이 필요했습니다.
불필요한 헤더 오버헤드: 많은 HTTP/1.1 요청들은 중복된 헤더를 포함하고 있어, 매 요청마다 불필요한 데이터를 전송해야 했습니다.
HTTP/2.0에서는 다음과 같은 변화가 있습니다.
HTTP/1.1 vs HTTP/2
1.
이진 프레이밍 계층(Binary Framing layer)
2.
멀티플렉싱
3.
헤더 압축
4.
서버 사이드 푸시
5.
스트림 우선순위
HTTP/1.0 ~ 1.1에 걸쳐, TCP 소켓 수준에서 보면 아래와 같은 개선이 이루어 졌습니다.

스트림

NOTE
HTTP/2의 가장 큰 변화는 텍스트 기반 프로토콜에서 바이너리 기반 프로토콜로 변화했으며, 각 데이터는 프레임 단위로 송수신을 합니다.
기존 text방식으로 HTTP 메시지를 보내는 방식은, 본문이 압축이 되지만 헤더는 압축이 되지 않으며 헤더 중복값이 있다는 문제 때문에 바이너리로 변경되었습니다.
HTTP/1.1은 헤더의 종단을 찾기 위해서 개행문자(빈 줄)을 찾을때까지 1바이트씩 미리 읽어 발견해야 했으며, 서버로서는 순차적으로 처리해야 했기 때문에 병렬처리가 어려웠습니다.
HTTP/2는 바이너리화 되어 TCP 소켓 레이어에서 데이터를 프레임 단위로 쉽게 분리가 가능해져, 수신 측 TCP 소켓의 버퍼를 빠르게 비울 수 있고, 다음 데이터를 고속으로 요청할 수 있습니다.
HTTP/1.1에서 HeaderBody는 개행 문자로 구분되지만, HTTP/2에서는 layer로 구분됩니다.
프레임 단위로 이루어진 요청과 응답 메세지는 하나의 스트림을 통해 이루어지며, 이러한 스트림들이 하나의 커넥션 내에서 병렬적으로 처리된다.
Frame > Message > Stream
Frame: Http/2에서 통신의 최소 단위이며, Header와 Data가 들어있습니다.
Message: HTTP/1.1과 마찬가지로 Request, Response의 단위이며, 다수의 Frame으로 구성됩니다.
Stream: 연결된 Connection 내에서 양방향으로 Message를 주고받는 흐름입니다.

헤더 압축

NOTE
HTTP/2는 반복되는 헤더 정보의 비효율성을 해결하기 위해 HPACK 압축 알고리즘을 사용해서 헤더 압축 기법을 사용합니다.
HPACK은 HTTP/2 헤더 필드를 압축하기 위한 전용 알고리즘이며, 주요 구성요소는 다음과 같습니다.
정적 테이블
미리 정의된 일반적인 헤더 필드의 목록
클라이언트와 서버는 모두 동일한 정적 테이블을 사용합니다.
동적 테이블
통신 중에 동적으로 생성되는 헤더 필드의 목록
클라이언트와 서버는 통신하면서 동적 테이블을 업데이트한다.
헤더 필드 인코딩
헤더 필드는 정적 테이블과, 동적 테이블의 인덱스를 사용하여 참조합니다.

예시

클라이언트가 2번의 요청을 보낸다고 가정해봅시다.
1.
:method, :path. :host 헤더가 포함된다.
클라이언트는 :method, :path, host 헤더를 보냅니다.
정적 테이블에 이미 있는 :method, :path는 인덱스로 참조되고, host는 동적 테이블에 추가됩니다.
2.
user-agent 헤더가 포함된다.
클라이언트는 동일한 :method, :path, host 헤더를 인덱스로 참조하고, 새로운 user-agent 헤더를 동적 테이블에 추가합니다.

멀티 플렉싱

NOTE
HTTP/2에서는 하나의 TCP 연결을 통해 여러 Stream이 동시에 열릴 수 있습니다. 이를 통해 HTTP/1.1의 HOL문제를 해결하며, Reqest/Response가 병럴로 처리될 수 있습니다.

HTTP/1.1 의 통신

1 TCP = 1 Request/Response가 규칙이며, 여러개의 요청을 보내기 위해서는 Connection을 여러번 생성해야 했다.
Connection을 만드는것은 한계가 있기 때문에 결국 수백개의 데이터를 던져야하는 요즘과 같은 경우에는 한께가 있었다.
여러개의 Request/Response를 하나의 Connection을 통해 처리할 수 있다. 대표적으로 index.html의 경우 HTML, CSS, JavaScript, 이미지 등 여러 리소스를 한번에 전송한다.
Framing Layer를 통해 바이너리 프레임 단위로 쪼갠다.

서버 푸시

NOTE
서버 푸시는 클라이언트가 요청하지 않은 리소스를 서버가 능동적으로 클라이언트에게 전송할 수 있는 기능입니다.
클라이언트가 HTML 파일을 요청하면 서버는 해당 HTML파일 뿐 아니라 CSS, JS와 같은 파일 등을 함께 전송할 수 있습니다. 클라이언트가 HTML파일을 분석하고 추가 리소스를 요청하기 전에 필요한 리소스를 미리 받아놓음으로써 로딩 속도를 개선할 수 있습니다.
멀티플렉싱 + 서버 푸시
1.
클라이언트가 index.html을 요청한다고 가정해봅시다.
2.
서버는 클라이언트의 요청에 대한 응답을 준비하면서, 클라이언트가 곧 필요로할 리소스를 파악합니다.
3.
서버는 Push Promise라는 특별한 프레임을 전송하여, 추가로 전송할 리소스들을 미리 알립니다.
4.
서버는 요청에 대한 응답과 함께 Push Promise에서 약속한 추가 리소스를 전송합니다.
5.
클라이언트는 전송된 리소스를 수신하고, 캐싱하여 다시 다운로드할 필요가 없도록 합니다.

스트림 우선순위

NOTE
HTTP/2에서는 각 스트림에 우선순위를 부여해, 클라이언트는 우선순위가 높은 리소스를 먼저 전송되도록 할 수 있습니다.
HTTP/2에서는 스트림 우선순위를 트리 구조로 표현합니다. 각 스트림은 부모 스트림을 가질 수 있으며, 형제 스틀미 간에는 우선순위가 매겨집니다.
HEADERS Frame: - Stream ID: 3 - Priority: - Stream Dependency: 0 - Weight: 200 HEADERS Frame: - Stream ID: 5 - Priority: - Stream Dependency: 0 - Weight: 100
Go
복사
Stream ID 3은 5보다 먼저 처리된다.
부모 스트림: 하나의 스트림은 다른 스트림의 우선순위 그룹에 속할 수 있으며, 부모가 먼저 처리된 후에 자식이 처리됩니다.
가중치: 1~256까지 값이 있으며, 높을수록 우선순위가 높습니다.
트리 기반 자원배분: 서버는 트리 구조와 가중치 값을 참고하여 자원을 배분합니다.

Fetch API

NOTE
Fetch APIXMLHttpRequest를 대체하는 최신 API로, 네트워크 요청을 더 간단하게 처리하며, 프로미스(Promise)기반의 비동기 작업을 지원합니다.
fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error));
JavaScript
복사
예제코드
XMLHttpRequest보다 오리진 서버 밖으로의 접근 및 CORS 제어가 쉬워진다.
캐시나 리다이렉트를 제어할 수 있다.
Service Worker 내에서 이용할 수 있다.

Fetchi API의 주요 특징