[ HTTP 완벽 가이드 ] 4장 정리 - 커넥션 관리 (1)

현주·2023년 11월 7일

HTTP 완벽 가이드

목록 보기
4/5

✏️ TCP 커넥션

HTTP 통신은 메세지를 전송할 때, 패킷 교환 네트워크 프로토콜들의 계층화된 집합인 TCP/IP를 통해 이루어진다.

일단 커넥션이 맺어지면, 클라이언트와 서버 간 주고받는 메시지는 안전하게 전달된다.

✔️ 패킷 교환 ( Packet switching )

  • 작은 블록의 패킷으로 데이터를 전송하며 데이터를 전송하는 동안만 네트워크 자원을 사용하도록 하는 방법
  • 컴퓨터 네트워크와 통신의 방식 중 하나로, 현재 가장 많은 사람들이 사용하는 통신 방식

✔️ HTTP / HTTPS 프로토콜 스택

✔ URL을 입력받은 브라우저가 수행하는 7단계

  1. 브라우저가 호스트명 추출
  2. 브라우저가 해당 호스트명에 대한 IP 주소 찾음
  3. 브라우저가 포트번호를 얻음
  4. 브라우저가 해당 IP의 해당 포트로 TCP 커넥션 생성
  5. 브라우저가 서버로 HTTP 요청 메시지 보냄
  6. 브라우저가 서버에서 온 HTTP 응답 메시지를 읽음
  7. 브라우저가 커넥션을 끊음

✔ TCP 커넥션의 특징

  1. 신뢰할 수 있는 데이터 전송 통로
    ➜ 인터넷을 안정적으로 연결하여 TCP 커넥션 한쪽에 있는 바이트들은 반대쪽으로 순서에 맞게 전달되기 때문에,
    클라이언트-서버 간에 주고받는 메시지들은 손실/손상되거나 순서가 바뀌지 않고 안전하게 전달

  2. TCP 스트림은 세그먼트로 나뉘어 IP 패킷을 통해 전송됨
    ➜ TCP는 데이터 스트림을 세그먼트 단위로 잘게 나눈 다음
    IP 패킷이라고 불리는 봉투에 담아 인터넷을 통해 데이터를 전달
    ➜ 각 TCP 세그먼트는 하나의 IP 주소에서 다른 IP 주소로 IP 패킷에 담겨 전달됨

✔️ IP 패킷
➜ TCP 데이터 스트림의 덩어리를 운반하는 TCP 세그먼트를 실어나르는 운반책

✔️ IP 패킷의 구성요소

  • IP 패킷 헤더 (보통 20byte)
    ➜ 발신지, 목적지 IP 주소, 크기, 기타 플래그 등을 포함
  • TCP 세그먼트 헤더 (보통 20byte)
    ➜ TCP 포트 번호, TCP 제어 플래그, 데이터 순서/무결성을 검사하기 위해 사용되는 숫자 값을 포함
  • TCP 데이터 조각 (세그먼트) (0 혹은 그 이상의 byte)

✔ TCP 커넥션의 구성요소

  • [ 발신지 IP 주소 / 발신지 포트 / 수신지 IP 주소 / 수신지 포트 ]의 네가지 부분으로 나뉨

➜ 이 네가지는 일부가 같을 수는 있지만 모두 같을 수는 없고, 이 네가지 값으로 유일한 커넥션을 생성


✏️ TCP 소켓 프로그래밍

✔ 소켓 ( Socket )

  • 프로그램이 네트워크에서 데이터를 송수신할 수 있도록 네트워크 환경에 연결할 수 있게 만들어진 연결부

  • 두 프로그램이 네트워크를 통해 서로 통신을 수행할 수 있도록 양쪽에 생성되는 링크의 단자

  • 두 소켓이 연결되면 서로 다른 프로세스끼리 데이터를 전달 가능

  • 상대방에게 데이터를 보내거나 받는 역할

✔ TCP/IP 소켓 통신

➜ 클라이언트 프로그램과 서버 프로그램은 각각 자신의 포트를 통해 통신을 해야 하는데, 소켓을 통해 연결함

✔ 소켓 API

  • 여러 기능들 중, 가장 널리 사용되는 표준 인터페이스

  • HTTP 프로그래머에게 TCP와 IP의 세부사항들을 숨김

  • 이를 사용하면, TCP 종단 (endpoint) 데이터 구조를 생성하고, 원격 서버의 TCP 종단에 그 조안 데이터 구조를 연결하여 데이터 스트림을 읽고 쓸 수 있음

✔️ 클라이언트 소켓과 서버 소켓
최초 어느 한 곳(클라이언트)에서 그 대상(서버)이 되는 곳으로 연결을 요청함
이는 IP 주소와 포트 번호로 식별되는 대상에게, 자신이 데이터 송수신을 위한 네트워크 연결 의사가 있음을 알리는 것임
그 대상(서버)이 요청을 받아들일 준비가 되어있지 않다면 요청은 무시되기 때문에 어떤 연결 요청을 받아들일 것인지 미리 알고 등록해야 함
연결을 요청하는 쪽이 클라이언트 소켓, 받아들이는 쪽이 서버 소켓
서버 소켓은 연결 요청을 받아들이는 연할만 수행할 뿐 새로 만들어지는 소켓으로 데이터를 통신함

참고 - 소켓 프로그래밍


✏️ TCP 성능 향상을 위해 고려해야할 것

  1. HTTP 트랜잭션 지연

  2. TCP 커넥션 핸드셰이크 지연

  3. 확인 응답 알고리즘 지연

  4. TCP 느린 시작 (slow start)

  5. 네이글(Nagle) 알고리즘 지연

  6. TIME_WAIT의 누적과 포트 고갈


(1) HTTP 트랜잭션 지연

➜ HTTP 트랜잭션의 성능은 그 아래 계층인 TCP 성능에 영향을 받음

✔️ HTTP 트랜잭션이 처리되는 과정
1. DNS 찾기
2. 클라이언트 - 서버 연결
3. 클라이언트 ➜ 서버 요청
4. 서버에서 요청 처리
5. 서버 ➜ 클라이언트 응답
6. 연결 종료

🧐 HTTP 트랜잭션 지연 이유

  1. HTTP 트랜잭션 처리 과정 중 1번에서 /
    URI의 호스트에 최근 방문한 적이 없을 경우,
    DNS 찾기 과정에서 DNS 이름 분석 인프라를 사용하여 URI의 호스트명을 IP 주소로 변환하는 과정에서 지연

  2. HTTP 트랜잭션 처리 과정 중 2번에서 /
    클 ➜ 서 연결 요청을 보내고 서버가 커넥션 허가 응답을 회신하기를 기다리는데,
    이 때 많은 HTTP 트랜잭션이 만들어진다면 소요시간 증가로 지연

  3. HTTP 트랜잭션 처리 과정 중 4번에서 /
    요청 메세지가 서버로 전달되고 처리되는 데 까지 시간이 걸리므로 지연

  4. HTTP 트랜잭션 처리 과정 중 5번에서 /
    서버가 HTTP 응답을 보내는 데 시간 소요로 지연


(2) TCP 커넥션 핸드셰이크 지연

새 TCP 커넥션을 열 때, TCP 소프트웨어는 커넥션을 맺기 위한 조건을 맞추기 위해 연속으로 IP 패킷을 교환하는데,

이 때, 작은 크기의 데이터 전송에 커넥션이 사용된다면 이런 패킷 교환은 HTTP 성능을 크게 저하시킬 수 있다.

✔️ TCP 커넥션의 핸드셰이크 순서
1. 클라이언트 ➜ 서버
새 TCP 커넥션 생성을 위해 작은 TCP 패킷을 보냄
( 커넥션 생성 요청이라는 뜻의 SYN이라는 플래그를 포함 )

2. 서버 ➜ 클라이언트
요청 허가를 의미하는 TCP 패킷을 보냄
( 커넥션 생성 요청 수락이라는 뜻의 SYNACK 플래그 포함 )

3. 클라이언트 ➜ 서버
커넥션이 잘 맺어졌음을 알리기 위해 서버에게 다시 확인 응답 신호 보냄
( 확인 응답 패킷과 함께 데이터 전송 가능 )

🧐 TCP 커넥션 핸드셰이크 지연 이유

➜ TCP의 ACK 패킷은 HTTP 요청 메시지 전체를 전달할 수 있을 만큼 큰 경우가 많고,
많은 HTTP 서버 응답 메시지는 하나의 IP 패킷에도 담길 수 있기 때문에,

자잘한 데이터를 주고받기 위해 하는 TCP 커넥션 연결 과정에서는 SYN/SYN+ACK 핸드셰이크가 눈에 띄는 지연을 발생 시킴

( 크기가 작은 HTTP 트랜잭션은 50% 이상의 시간을 TCP를 구성하는 데 씀 )


(3) 확인 응답 알고리즘 지연

인터넷 자체가 패킷 전송을 완벽히 보장하지는 않기 때문에,
( 인터넷 라우터는 과부하가 걸렸을 때 패킷을 마음대로 파기 가능 )

성공적인 데이터 전송 보장을 위해 TCP는 자체적인 확인 체계를 가진다.

각 세그먼트 - 순번, 데이터 무결설 체크섬 가짐
각 세그먼트 수신자 - 세그먼트 잘 받으면 확인 응답 패킷을 송신자에게 반환

송신자가 확인응답을 특정 시간 안에 못받으면 데이터를 다시 전송

보통 확인 응답은 데이터 크기가 작아서 갈 길이 같은 데이터 패킷이 있으면 같이 편승시켜서 보냄

이런 편승되는 경우를 늘리기 위해 확인 응답 지연 알고리즘 구현했음

✔️ 확인 응답 지연 알고리즘
1. 확인 응답을 특정 시간(보통 0.1 ~ 0.2초)동안 버퍼에 저장해두고,
2. 편승시킬만한 적절한 송출 데이터 패킷을 찾음
3. 여기서 찾으면 같이 보내고 / 일정 시간동안 못찾으면 별도 패킷으로 확인 응답만 보내짐

🧐 확인 응답 알고리즘 지연 이유

➜ HTTP 동작 방식은 요청/응답 두개밖에 없어서
확인 응답을 편승시킬 같은 방향의 데이터 패킷을 찾기 힘들기 때문에
이 알고리즘에서 지연이 자주 발생함 !


(4) TCP 느린 시작 (slow start)

✔️ TCP 느린 시작
➜ HTTP는 처음에는 속도를 제한(느리게 시작)하여 확인 응답을 받고,
점점 데이터가 성공적으로 전송됨에 따라 속도 제한을 높여 나감
( 자체적으로 튜닝 )
➜ 인터넷의 급작스러운 부하/혼잡을 방지하기 위해 사용

이는 TCP가 한번에 전송할 수 있는 패킷의 수를 제한하므로,
전송할 데이터 양이 많아도 한번에 못보냄

Ex. 처음엔 1개 패킷 전달 ➜ 확인 응답 받고 2개 전달 ➜ 확인 응답 받고 4개 전달 이런식
( 이걸 '혼잡 윈도를 연다'라고 함 )

따라서 이 혼잡제어 기능 때문에,
새로운 커넥션은 이미 어느정도 데이터를 주고받은 튜닝된 커넥션보다 느림
👉 HTTP는 이미 존재하는 커넥션을 재사용하는 지속 커넥션 기능이 존재


(5) 네이글(Nagle) 알고리즘 지연

✔ 네이글 알고리즘이 생긴 배경

TCP는 데이터 스트림 인터페이스를 제공하여
애플리케이션이 어떤 크기의 데이터든지 TCP 스택으로 전송할 수 있도록 하는데,
TCP는 각 세그먼트에 40바이트 상당의 플래그/헤더를 포함시켜서 전송하기 때문에
작은 크기의 데이터만 포함한 패킷들을 많이 전송하게되면 네트워크 성능 떨어짐

👉 네이글 알고리즘 생김

✔️ 네이글(Nagle) 알고리즘
➜ 패킷 전송 전에 TCP 데이터들을 한개의 덩어리로 합쳐서 전송하는 것
➜ 세그먼트 최대 크기가 되지 않으면 전송 X
( 모든 패킷이 확인 응답 받았을 경우에만 작은 패킷 전송 허락 )
➜ 데이터를 버퍼에 저장해놓았다가, 기다리던 패킷이 확인 응답 받았거나 / 전송하기 충분한 양의 패킷이 쌓여있을 때 버퍼에 모아뒀던 거 꺼내서 전송

🧐 네이글(Nagle) 알고리즘의 성능 문제로 인한 지연 이유

  1. 다음 데이터가 언제 올 지도 모르는데 세그먼트 채워질 때까지 못보내고 계속 기다려야함

  2. 확인 응답 지연 알고리즘과 함께 쓰이면 형편 없이 동작
    ( 확인 응답도 100~200 밀리초 정도 지연되는데 네이글도 확인 응답이 도착할 때까지 데이터 전송 멈춰야함 )

👉 성능을 향상시키기 위해 HTTP 스택에 TCP_NODELAY 파라미터 값 설정해서 네이글 비활성화 시키기도 함
( 근데 이거 설정하면 작은 크기의 패킷 너무 많이 생기지 않도록 최대한 큰 크리의 데이터 덩어리들을 전송해야함 )


(6) TIME_WAIT의 누적과 포트 고갈

➜ 보통 실제 상황에서는 문제가 없고 성능 측정 시에 심각한 성능 저하를 발생시키는 원인임

TCP 커넥션의 끝에서 커넥션을 끝으면, 해당 커넥션의 IP 주소와 포트번호를 메모리의 작은 제어 영역(control block)에 기록해놓고
보통 세그먼트의 최대 생명주기에 두 배 정도(보통 2분)의 시간동안 유지함

➜ 같은 주소와 포트번호를 사용하는 새 커넥션이 약 2분 이내에 또 생성되는 것을 막아줌
( 시간이 정해진 블랙리스트같은 느낌으로다가 )

( 이전 커넥션과 관련된 패킷이 그 커넥션과 같은 주소와 포트 번호를 가지는 새 커넥션에 삽입되는 문제를 방지 )

이는 보통 실제 상황에서는 문제가 없는데,
성능 측정 시에는 클라이언트가 접속할 수 이쓴 IP 주소의 개수를 제한하고, 적은 컴퓨터로 많은 부하를 만들어야하기 때문에
[발신지 IP 주소 / 발신지 포트 / 목적지 IP 주소 / 목적지 포트]의 조합이 다 달라야하는 TCP 커넥션 특성 상,
TIME_WAIT로 인해 순간순간 포트를 재활용하는 것이 불가능해져 지연이 일어남

보통 120초(2분)동안 커넥션이 재사용될 수 없으므로, 초당 약 500개의 커넥션이 제한된다.

만약 서버가 초당 500개 이상의 트랜잭션을 처리할 만큼 빠르지 않다면 TIME_WAIT 포트 고갈은 일어나지 않음

이 문제를 해결하기 위해서는 부하를 생성하는 장비를 더 많이 사용하거나, 여러개의 가상 IP 주소로 클-서 가 더 많은 커넥션을 맺을 수 있도록 하는 방법이 있음

0개의 댓글