HTTP 파헤치기

김상민·2024년 3월 4일
0

Web

목록 보기
3/4
post-thumbnail

📖 HTTP의 발전

📑 HTTP/0.9

문제점

  • GET method만 존재
  • header 없음
  • HTML만 가져오도록 설계(이미지는 처리할 수 없고 텍스트만 다룰 수 있었음)

📑 HTTP/1.0

개선점

  • header 도입
  • 응답 코드
  • 리다이렉트
  • 오류
  • 조건부 요청
  • 콘텐츠 압축
  • 다양한 요청 메서드

문제점

  • 한 연결당 하나의 요청만 처리 ⇒ RTT 증가
  • 서버가 하나의 호스트만 가진다고 가정함 ⇒ Host header 필수 아님
  • 캐싱 옵션 빈약

📑 HTTP/1.1

개선점

  • Keep-Alive default (접속 재사용) ⇒ 응답 후에 연결을 끊지 않음, 모든 요청마다 TCP 연결을 재수립하지 않아도 됨
    import express from "express";
    
    const app = express();
    app.get("/", (req, res) => {
        res.json({ title: "Hello I'm Sangmin" });
    });
    
    const server = app.listen(4000);
    server.keepAliveTimeout = 30 * 1000;
  • Host header ⇒ 하나의 IP 주소로 다수의 웹 프로퍼티 제공(하나의 서버가 여러개의 호스트를 가질 수 있음)
  • 대역폭 최적화 ⇒ 파일을 다운로드 받다가 연결이 끊겨도 다운로드 재개 요청을 할 수 있는 헤더 추가(Range:bytes=5000-)
  • XMLHttpRequest
  • TLS 암호화 통신

문제점

  • 리소스 우선순위 없이 받아짐. 렌더링 비효율
  • 헤더 크기가 너무 큼(쿠키 같은 메타데이터들 때문)
  • 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/3HTTP/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인가?가 아니라 커널 공간인가, 사용자 공간인가?를 생각하는게 논쟁의 핵심!

🪖 HTTP Header

Body를 설명하는 정보를 포함헤서 여러가지 정보가 담긴 정보 묶음.

콜론으로 구분되는 key-value 형태

3가지 헤더가 자동으로 생김

  • 일반헤더

    요청 URL, 메서드, 상태코드, Refferrer Policy(자원을 요청할 때 출처 노출을 시킬지 말지 정하는 보안 정도 설정) 등

  • 요청헤더

    클라이언트에서 설정하거나 자동으로 설정됨
    메서드, 클라이언트 OS, 브라우저 정보

  • 응답헤더

    서버에서 설정하는 헤더
    서버의 소프트웨어 정보(프록시 서버 등)

참고

러닝 HTTP/2

profile
성장하는 웹 프론트엔드 개발자 입니다.

0개의 댓글