본 내용은 "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 연결은 다음 네 가지 요소의 조합으로 식별된다.
- 발신지 IP 주소
- 발신지 포트
- 수신지 IP 주소
- 수신지 포트
이 네 가지가 합쳐진 조합은 반드시 유일해야 하며, 서로 다른 커넥션끼리 중복되어서는 안 된다.
위 예시에서 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
- 네이글 알고리즘은 작은 데이터가 자주 전송될 경우, 더 큰 세그먼트로 합쳐 전송함으로써 패킷 낭비를 줄이기 위한 방식이다.
- 구체적으로,
- 버퍼에 모은 데이터가 최대 세그먼트 크기에 도달하면 즉시 전송
- 이전에 전송한 세그먼트에 대한 ACK를 모두 받으면 즉시 전송
- 그 외에는 버퍼에 계속 데이터를 모음
- 하지만 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 |