📖 HTTP의 발전
📑 HTTP/0.9
문제점
- GET method만 존재
- header 없음
- HTML만 가져오도록 설계(이미지는 처리할 수 없고 텍스트만 다룰 수 있었음)
📑 HTTP/1.0
개선점
- header 도입
- 응답 코드
- 리다이렉트
- 오류
- 조건부 요청
- 콘텐츠 압축
- 다양한 요청 메서드
문제점
- 한 연결당 하나의 요청만 처리 ⇒ RTT 증가
- 서버가 하나의 호스트만 가진다고 가정함 ⇒ Host header 필수 아님
- 캐싱 옵션 빈약
📑 HTTP/1.1
개선점
문제점
- 리소스 우선순위 없이 받아짐. 렌더링 비효율
- 헤더 크기가 너무 큼(쿠키 같은 메타데이터들 때문)
- keep-alive를 사용하더라도 단일 연결에서 처리할 수 있는 요청의 수가 제한되어 있고, HOL문제가 있음
HOL(Head of Line Bloking)
네트워크에서 같은 큐에 있는 패킷이 앞의 지연 패킷 때문에 발생하는 성능 저하 현상
- HTML 파일, CSS 파일, 이미지 등을 동시에 요청하고 받기 위해 여러개의 연결(connection)을 사용해야만 함
RTT를 줄이기 위한 기술
- 이미지 스프라이트
- 코드압축
- 이미지 Base64 인코딩
📑 SPDY
📑 HTTP/2
- 구글의 SPDY에서 출발
- HTTP 1.1 까지의 핵심기능 유지하며 확장.
개선점
- 멀티플렉싱
리소스를 작은 프레임으로 나누고 이를 스트림으로 프레임을 전달.
각각의 프레임은 스트림id, 청크의 크기를 전달하여 병력적으로 다운하고 재조립 가능
⇒ HOL 해결
-
여러개의 스트림을 동시에 전송.
-
하나의 스트림은 여러개의 프레임으로 구성.
- 1번 스트림: 프레임 A, 프레임 B, 프레임 C
- 2번 스트림: 프레임 X, 프레임 Y, 프레임 Z
-
프레임은 각각의 고유한 ID를 가지며 독립적으로 전송.
-
이처럼 HTTP/2 에서는 병렬로 전송되는 스트림과 프레임을 통해 HTTP/2은 다중 요청 및 응답을 동시에 처리하고, 성능을 개선.
스트림: 스트림은 독립적인 양방향 데이터 흐름. 각 스트림에는 고유한 식별자가 있으며, 하나의 연결 내에서 병렬로 여러 스트림이 동시에 활성화 가능
프레임: 프레임은 스트림에 속하는 가장 작은 통신 단위로, 헤더 프레임, 데이터 프레임 등 다양한 종류가 있음. 각 스트림은 하나 이상의 프레임으로 구성
- Header 압축
서버에서 중복되는 헤더는 제외하고 공통 필드로 헤더를 재구성
중복되지 않은 헤더 값은 허프만 인코딩 압축 후 전송
허프만 인코딩: 문자열을 문자 단위로 쪼개서 빈도수를 세어 빈도가 높은 정보는 적은 비트수, 낮은 정보는 많은 비트 수를 사용해서 전체 비트 수를 줄이는 알고리즘
- Server Push
서버가 클라이언트에 리소스를 푸시할 수 있다.
- 우선순위
서버가 원하는 순서대로 우선순위를 정해 리소스를 전달
📑 HTTP/3
UDP의 단순하고, 낮은 오버헤드의 장점을 살리자!
- QUIC(Quick UDP Internet Connection)위에서 동작 QUIC는 HTTP/2에 상응하는 다중화와 흐름제어, TLS에 상응하는 보안성, TCP에 상응하는 연결 의미, 신뢰성, 혼잡제어를 제공한다.
- QUIC은 UDP 위에서 동작.
- HTTP/2의 경우 클라이언트와 서버간의 연결을 맺어 세션을 만드는데 필요한 핸드셰이크와 TLS 핸드셰이크가 각각 필요.
HTTP/3에서는 TLS 1.3 암호화를 프로토콜에 내장하여, 한 번의 핸드셰이크로 연결과 암호화통신 모두 구축
⇒ 3-RTT에서 1-RTT로
- HTTP/3도 여러개의 stream 을 사용하고 그 안에서 여러개의 프레임이 존재함. 따라서 HTTP/2과 같이 여러 개의 요청과 응답이 하나의 연결(커넥션)에서 동시에 처리될 수 있음. 다만 HTTP/3은 HTTP/2과 달리 프레임이 UDP 패킷단위로 나눠져 있음.
- HTTP/3에서는 UDP 그리고 부족한 신뢰성을 극복하기 위해 패킷 손실등의 방안을 추가. QUIC 프로토콜은 패킷에 일련번호를 부여함
TCP의 재전송 메커니즘과 유사하게 패킷 재전송
- UDP 패킷 레벨에서 데이터를 분할하고 전송. TCP 패킷보다 더 작은 패킷사용해서 패킷 손실시 영향이 적음
TCP vs UDP
🤔 TCP....
- 3-way handshake 및 4-way handshake 과정을 거치기 때문에 추가적인 오버헤드가 발생
- TCP는 데이터의 신뢰성과 네트워크 혼잡제어 알고리즘 사용
- 느린 시작 (Slow Start) 연결 초기에 TCP는 네트워크의 혼잡 수준을 알 수 없으므로, 작은 양의 데이터로 시작하여 네트워크의 용량을 점진적으로 탐색. 데이터 전송률은 지수적으로 증가하며, 이는 "혼잡 윈도우(congestion window)"의 크기가 각 RTT(Round-Trip Time)마다 두 배로 증가
혼잡 윈도우: 수신자가 확인(ACK)하기 전까지 송신자가 전송할 수 있는 TCP 패킷의 수
- 혼잡 회피 (Congestion Avoidance) 느린 시작 단계에서 혼잡 윈도우가 일정 임계값(ssthresh, slow start threshold)에 도달하면, TCP는 혼잡 회피 모드로 전환. 이 모드에서는 혼잡 윈도우의 크기를 선형적으로 증가시켜 네트워크 혼잡을 회피 윈도우 사이즈를 늘려나가다 패킷이 전송되지 않거나
TIME_OUT
이 발생하면 늘려놨던 윈도우 사이즈를 절반으로 줄임
- 빠른 재전송 (Fast Retransmit) 및 빠른 회복 (Fast Recovery) 패킷 손실을 감지할 때, TCP는 빠른 재전송 알고리즘을 사용하여 해당 패킷을 즉시 재전송. 빠른 회복 알고리즘은 혼잡 윈도우의 크기를 조정하여 네트워크의 혼잡 상태를 빠르게 극복
🧐 UDP..?
- 다른 방법은? UDP...? 그건 신뢰성을 보장하지 못하는데..
DNS 같은 단순 프로토콜이나 음성채팅에서 사용
🥊 TCP vs UDP
UDP 기반으로 프로토콜을 바꾸려면, 연결이라는 개념을 구현하고, 신뢰성을 높이고, 혼잡제어도 있어야함. 즉 TCP의 많은 것을 다시 구현해야함
But,
TCP 스택은 커널 공간에 구현되어 있음. 즉 OS 개발사가 OS를 업데이트 해야 커널을 변경할 수 있음
OS를 업데이트 하는 건 브라우저를 업데이트 하는 것에 비해 복잡한 일
따라서 UDP 기반으로 사용자 공간(브라우저 내부)에서 TCP 스택을 다시 구현하면 브라우저 업데이트 만으로 사용자가 새 버전을 사용할 수 있음
🥊 커널 공간 vs 사용자 공간
TCP인가, UDP인가?가 아니라 커널 공간인가, 사용자 공간인가?를 생각하는게 논쟁의 핵심!
Body를 설명하는 정보를 포함헤서 여러가지 정보가 담긴 정보 묶음.
콜론으로 구분되는 key-value 형태
3가지 헤더가 자동으로 생김
-
일반헤더
요청 URL, 메서드, 상태코드, Refferrer Policy(자원을 요청할 때 출처 노출을 시킬지 말지 정하는 보안 정도 설정) 등
-
요청헤더
클라이언트에서 설정하거나 자동으로 설정됨
메서드, 클라이언트 OS, 브라우저 정보
-
응답헤더
서버에서 설정하는 헤더
서버의 소프트웨어 정보(프록시 서버 등)
참고
러닝 HTTP/2