이 글에서 얻는 것

  • TCP가 “연결”을 만들고 끊는 과정(Handshake/Close/TIME_WAIT)을 이해하고, 타임아웃/연결 재사용 이슈를 설명할 수 있습니다.
  • 흐름 제어(Flow)와 혼잡 제어(Congestion)를 구분해서, “왜 느린지”를 RTT/대역폭/패킷 손실 관점으로 생각할 수 있습니다.
  • HTTP/2의 핵심(멀티플렉싱/헤더 압축/스트림)을 알고, HTTP/1.1 대비 어떤 문제가 줄고 어떤 문제는 남는지 판단할 수 있습니다.
  • 프로덕션에서 HTTP/2가 “켜져 있는지/어디서 종료되는지”를 확인하는 기본 점검 포인트를 정리합니다.

1) TCP: 연결을 만든다는 것의 의미

HTTP 요청 하나도 결국 TCP 위에서 오갑니다. TCP에서 핵심은 “신뢰성”을 위해 연결 상태를 유지하고, 순서 보장/재전송/흐름 제어/혼잡 제어를 수행한다는 점입니다.

3-way Handshake(연결 수립)

  1. SYN (클라이언트 → 서버)
  2. SYN-ACK (서버 → 클라이언트)
  3. ACK (클라이언트 → 서버)

핵심 감각:

  • RTT(왕복 지연)가 큰 환경일수록 “연결을 새로 만드는 비용”이 커집니다. → 그래서 Keep-Alive/커넥션 풀/재사용이 중요합니다.

4-way Close와 TIME_WAIT

연결 종료는 양방향이므로 보통 4번의 메시지가 오갑니다. 그리고 종료 후 한쪽은 TIME_WAIT에 머뭅니다.

  • 목적: 지연된 패킷이 다음 연결에 섞이는 것을 방지, 마지막 ACK 유실 대비
  • 증상: 단시간에 많은 단기 연결을 만들면 TIME_WAIT가 늘어나고 포트 고갈/연결 실패로 이어질 수 있습니다.

2) 흐름 제어 vs 혼잡 제어: “상대가 못 받는 문제” vs “네트워크가 못 버티는 문제”

흐름 제어(Flow control)

수신 측이 “내가 지금 이만큼까지는 받을 수 있어”를 윈도(window)로 알려서, 버퍼 오버플로우를 막습니다.

혼잡 제어(Congestion control)

네트워크 중간(라우터/망)이 붐비면 패킷 손실/지연이 증가합니다. 이때 송신 측이 전송량을 조절합니다.

감각적으로는:

  • RTT가 크거나 손실이 있는 환경에서는 처리량이 급격히 떨어질 수 있습니다.
  • “서버가 빠른데도 느리다”면 애플리케이션보다 네트워크/혼잡/재전송이 원인일 수 있습니다.

3) HTTP/2: 한 커넥션으로 여러 요청을 동시에

HTTP/1.1의 대표적인 병목은 “한 커넥션에서 요청/응답이 줄줄이 막히는” 구조였습니다(파이프라이닝 한계, 커넥션 증가). HTTP/2는 한 TCP 커넥션 안에 여러 스트림(Stream) 을 두고 멀티플렉싱합니다.

핵심 특징:

  • 멀티플렉싱: 한 커넥션에서 여러 요청/응답을 동시에 흘려 보냄 → 커넥션 수 감소, 헤더 반복 감소
  • HPACK 헤더 압축: 헤더 크기를 줄여 오버헤드 감소
  • 서버 푸시: 한때 기대가 컸지만 운용 복잡도 때문에 현재는 보수적으로 접근(대부분 비권장)

주의: HTTP/2가 “모든 HOL Blocking을 없애는 것”은 아닙니다. TCP 레벨에서 패킷 손실이 나면 같은 커넥션 안의 스트림들이 영향을 받을 수 있습니다. (이 문제를 더 줄이려는 접근이 HTTP/3(QUIC)입니다.)

4) 실무 점검 포인트(최소)

  • 커넥션 재사용이 되는가: Keep-Alive/커넥션 풀/프록시 설정
  • HTTP/2 협상이 되는가: TLS + ALPN(대부분의 브라우저/프로덕션 환경)
  • 어디서 h2가 종료되는가: CDN/LB/프록시가 h2를 받고, 백엔드로는 h1.1로 내려보내는 경우가 흔합니다.
  • 다운그레이드 시 영향: h2 → h1.1로 떨어지면 커넥션 수/지연/헤더 오버헤드가 증가할 수 있습니다.

연습(추천)

  • curl -v --http2 https://example.com로 ALPN 협상과 프로토콜을 확인해보기
  • 같은 엔드포인트에 병렬 요청을 날려서 h1.1(다중 커넥션) vs h2(단일 커넥션)의 차이를 체감해보기