CS Repo/HTTP 완벽 가이드

HTTP에서 바라본 TCP 커넥션 관리 방식

조금씩 차근차근 2025. 3. 27. 20:46

본 내용은 "HTTP 완벽 가이드" 내용을 참고하여 기록한 정리본입니다.

게시할 내용

  • HTTP의 커넥션 사용 방식
  • TCP의 구조
    • TCP 지연
    • TCP 병목
    • TCP 막힘
  • 흐름제어/혼잡제어

HTTP 네트워크 프로토콜 스택

HTTP는 전송 계층인 TCP 위에서 동작하며, IP 계층을 통해 패킷이 전달된다. 이 과정에서 여러 계층을 거치기 때문에, 각 계층이 가진 헤더(메타데이터)들이 포함되어 전송된다.

HTTPS

HTTPS는 위의 HTTP 네트워크 프로토콜 스택에 SSL/TLS를 위한 보안 계층을 추가한 프로토콜이다. SSL/TLS 계층에서 암호화, 무결성 보장, 인증 등의 과정을 거친 후에 TCP 계층에 데이터를 전달하기 때문에, 일반 HTTP보다 연결 과정이 조금 더 복잡하고 느리다.

그러나 전송되는 내용이 암호화되어 보안성을 높이기 때문에, 오늘날 대부분의 웹 서비스가 HTTPS를 사용한다.


TCP 커넥션의 특징

전송 방식

  • TCP 스트림
    • TCP는 바이트 스트림(byte stream) 방식으로 데이터를 전송한다. 이 스트림은 일정 크기의 TCP 세그먼트로 잘게 나누어지며, 세그먼트 단위로 전송된다.
  • TCP 세그먼트
    • TCP 스트림을 네트워크 계층에서 다루기 쉽게 쪼갠 단위다. 세그먼트에는 TCP 헤더가 붙으며, 이 세그먼트를 IP 계층이 받아서 IP 패킷으로 캡슐화한다.
  • IP 패킷
    • 네트워크 계층에서 전송되는 데이터 블록이다. IP 패킷에는 IP 패킷 헤더(보통 20바이트), TCP 세그먼트 헤더(보통 20바이트), 그리고 TCP 데이터가 포함된다.

커넥션 정보 저장 방식

TCP 연결은 다음 네 가지 요소의 조합으로 식별된다.

  1. 발신지 IP 주소
  2. 발신지 포트
  3. 수신지 IP 주소
  4. 수신지 포트

이 네 가지가 합쳐진 조합은 반드시 유일해야 하며, 서로 다른 커넥션끼리 중복되어서는 안 된다.

위 예시에서 A, B, C, D 각각의 연결은 발신지·수신지 IP 및 포트 번호가 달라 서로 구분이 가능하다.

실제 TCP 통신 방법

실제로 TCP 통신이 어떤 방식으로 이뤄지는지는 아래 링크에서 자세히 살펴볼 수 있다.

https://go-gradually.tistory.com/entry/네트워크-소켓-통신


HTTP 트랜잭션이 처리되는 과정

HTTP 트랜잭션은 단순히 “요청-처리-응답”으로만 끝나는 것이 아니라, DNS 쿼리TCP 핸드셰이크 등 다양한 외부 요소가 시간을 잡아먹는다.

  • DNS 조회가 오래 걸리는 경우
  • 커넥션을 새로 맺는 과정이 반복되는 경우
  • TCP의 슬로우 스타트로 속도가 곧바로 높아지지 않는 경우

이러한 이유로 요청과 응답 자체는 금방 처리되더라도, 실제 사용자 체감 속도는 그만큼 빠르지 않을 수 있다.


TCP 성능 오버헤드 - TCP 위주로 알아보기

HTTP가 TCP 위에서 동작하다 보니, TCP의 성능 특성이 HTTP 트랜잭션에도 직접적인 영향을 끼친다. 아래는 대표적인 TCP 오버헤드 항목들이다.

TCP 커넥션 핸드셰이크 지연

TCP는 커넥션을 맺을 때 3-way 핸드셰이크 과정을 거친다. 보통은 SYN → SYN+ACK → ACK 순서로 패킷이 왕복되는데, 여기서 SYN과 SYN+ACK 구간이 전체 HTTP 트랜잭션 시간의 절반 정도를 차지하기도 한다.

  • 최근에는 ACK 사이에 요청을 같이 보내는 기법(예: TFO, TCP Fast Open)을 통해, 핸드셰이크 시간을 줄이는 시도가 있다.
  • 연결을 자주 맺고 끊는 환경이라면, 커넥션 재활용(Keep-Alive, 파이프라이닝, HTTP/2, HTTP/3 등)을 고려해볼 수 있다.

확인응답 지연

TCP는 신뢰성을 보장하기 위해 세그먼트를 전송할 때마다 상대방으로부터 확인응답(ACK)을 받아야 한다.

  • 송신자는 정해진 시간 안에 ACK를 받지 못하면, 해당 데이터를 재전송한다.
  • ACK 패킷은 매우 작은 크기이므로, 반대 방향으로 전송될 데이터 패킷에 함께 실어 보내는 “piggyback”을 활용하기도 한다.
  • 이때 확인응답 지연 알고리즘으로 인해 TCP가 ACK를 일정 시간(일반적으로 0.1~0.2초) 모으고 있다가 데이터를 보낼 기회가 생기면 같이 보낼 수 있다.
  • 하지만 요청/응답 위주인 HTTP는 그런 전송 기회가 많지 않아, 이 지연 알고리즘이 오히려 성능을 떨어뜨리는 상황이 생길 수 있다.
  • 특정 환경에서는 ACK 지연 기능을 끄고 사용하는 경우도 있다.

TCP 슬로우 스타트(느린 시작)

TCP는 혼잡을 피하기 위해 전송 속도를 점진적으로 올린다. 이를 슬로우 스타트(slow start)라고 한다.

  • 연결이 막 생겼을 때나 네트워크 상태를 새로 파악해야 할 때, 전송 윈도우 크기가 매우 작아서 전송량이 제한된다.
  • 시간이 지남에 따라 성공적으로 패킷을 전달했다고 판단되면, 윈도우 크기를 늘려 전송 속도를 높인다.
  • 따라서 오랫동안 유지된 연결은 이미 윈도우 크기가 커져 빠르게 전송할 수 있지만, 새로 맺은 연결은 한동안 낮은 전송 속도를 갖게 된다.
  • 이 때문에 새로운 커넥션보다는 재사용 가능한 커넥션을 유지하는 것이 유리하다고 보는 시각이 있다.

네이글 알고리즘, TCP_NODELAY

  • 네이글 알고리즘은 작은 데이터가 자주 전송될 경우, 더 큰 세그먼트로 합쳐 전송함으로써 패킷 낭비를 줄이기 위한 방식이다.
  • 구체적으로,
    1. 버퍼에 모은 데이터가 최대 세그먼트 크기에 도달하면 즉시 전송
    2. 이전에 전송한 세그먼트에 대한 ACK를 모두 받으면 즉시 전송
    3. 그 외에는 버퍼에 계속 데이터를 모음
  • 하지만 HTTP 메시지처럼 크기가 작고 요청-응답 패턴이 잦은 경우, 네이글 알고리즘과 ACK 지연이 동시에 작동하면 지연이 더욱 커질 수 있다.
  • 이때 TCP_NODELAY 옵션을 활성화해 네이글 알고리즘을 끄면, 작은 패킷도 즉시 전송이 가능해진다. 단, 그만큼 패킷이 자주 발생하므로, 전송 효율을 관리할 필요가 있다.

TIME_WAIT의 누적과 포트 고갈

TIME_WAIT란?

  • TCP 커넥션을 끊으면, 같은 주소와 포트 번호를 사용하는 새로운 TCP 커넥션이 일정 시간동안 생성되지 않게 하기 위한 상태이다.
  • <송신자 IP, 송신자 Port, 수신자 IP, 수신자 Port> 로 연결을 구분하여 TIME_WAIT 상태를 유지한다.

예시

  • TCP는 송신자/수신자의 IP/포트번호로 구분한다.
  • 연결이 닫혔다가 다시 생성되면, 개념 상 다르지만, 같은 식별자를 갖는 커넥션이 2개 존재한다고 할 수 있다.

  • 만약 앞서 있던 패킷이 지연 송신되어서, 뒷 커넥션이 열려있을 때 도착했다고 해보자.
  • 시점이 다르면, 만날 일은 없겠지만, 만약 비슷한 시점에 발생하면, 구분할 방법이 없다.
  • 그래서 그냥, 같은 송신자/수신자의 IP/포트번호로는 커넥션이 일정 시간동안 생성이 안되도록 막는 것이다.
  • 일반적으로는, control block 에 2분간 기록해둔다.
    • 세그먼트의 최대 생명주기(1분) * 2
    • 이 시간은 커널 헤더에 하드코딩 되어 있음
  • 참고로, 현대의 라우터들은 훨씬 빨라서, 커넥션이 닫힌 후에 중복되는 패킷이 생성되는 경우가 거의 없다고 한다.

TIME_WAIT의 성능 테스트 시 문제점

TCP 커넥션을 끊은 후에는 TIME_WAIT 상태로 일정 시간(일반적으로 2분) 대기한다. 이 기간에는 같은 (발신지 IP, 발신지 포트, 수신지 IP, 수신지 포트) 조합으로 새 커넥션을 맺을 수 없다.

  • 네트워크 혼잡이나 패킷 지연으로 인해 늦게 도착한 중복 패킷이 새로운 연결에 영향을 주지 않도록 하는 장치다.
  • 실제 서비스 환경에서는 여러 클라이언트 IP와 포트를 사용하므로 포트가 쉽게 고갈되지 않는다.
  • 테스트 환경처럼 클라이언트가 적고 포트 재사용이 빠르게 이루어져야 하는 경우에는, TIME_WAIT가 누적되어 부하 테스트 중 성능 문제가 발생한 것처럼 보일 수 있다.
  • 이는 실 서비스 성능 문제와는 직접적인 연관이 없는 경우가 많으므로 주의가 필요하다.

간단하게 정리한 흐름제어/혼잡제어

  • 흐름제어(Flow Control)
    • 수신자가 현재 처리할 수 있는 데이터 양을 송신자에게 알려줌으로써, 수신 측 오버플로를 방지한다.
  • 혼잡제어(Congestion Control)
    • 네트워크 전체가 혼잡해지는 것을 피하기 위해, 송신자가 처음부터 많은 데이터를 보내지 않고 조금씩 전송량을 늘려간다.
      • 네트워크 상태를 보면서 패킷 손실이 없으면 전송 윈도우를 점차 키운다.
      • 패킷 손실이 발생하면 전송 윈도우를 줄이면서 신중하게 속도를 조절한다.

'CS Repo > HTTP 완벽 가이드' 카테고리의 다른 글

웹 서버  (0) 2025.04.04
HTTP 커넥션 관리 최적화 기법  (0) 2025.04.03
HTTP 메시지  (0) 2025.03.25
URL과 리소스  (0) 2025.03.24
HTTP란?  (0) 2025.03.24