열렬히.뛰기

4. 커넥션 관리

네트워크 > HTTP 완벽 가이드 > HTTP 완벽 가이드 > 4. 커넥션 관리

TCP 커넥션

HTTP 통신은 TCP/IP를 통해 이뤄진다.

  • TCP/IP → 패킷 교환용 프로토콜
  • 다음 그림과 같은 단계를 수행한다고 보면 된다.

간단한 TCP 작동원리

  • TCP는 세그먼트라는 단위로 데이터 스트림을 잘게 나누고, 세그먼트를 IP 패킷이라는 봉투에 담아서 인터넷을 통해 데이터를 전달한다.
  • TCP 세그먼트는 IP 패킷에 담겨서 전송되고, 각 IP 패킷들 각각은 다음을 포함한다.
    • IP 패킷 헤더 : 발신자와 목적지 IP 주소, 크기, 기타 플래그를 가짐.
    • TCP 세그먼트 헤더 : TCP 포트 번호, TCP 제어 플래그, 데이터의 순서 및 무결성 검사용 숫자
    • TCP 데이터 조각

TCP 커넥션 유지하기

  • TCP는 포트 번호를 통해서 여러개의 커넥션을 유지
  • 커넥션은 4가지 값으로 유지 ⇒ 발신자 IP주소, 발신자 포트, 수신자 IP주소, 수신자 포트

소켓 프로그래밍

  • TCP 커넥션을 실제로 코드로 짜려면 소켓 API가 필요
  • 처음에는 유닉스용이었지만, 지금은 대부분의 언어가 지원

TCP 성능에 대한 고려

HTTP는 TCP 위에 있는 계층이므로, HTTP의 성능은 TCP의 성능에 영향을 무조건 받음.

따라서 TCP 커넥션의 성능에 대한 고려를 하는 것이 HTTP 어플리케이션 설계에 도움을 준다.

HTTP 트랜잭션을 지연시키는 원인

  1. URI 호스트명 → IP 주소 변환 과정에서 지연 (DNS 문제)
  2. 수백 개의 HTTP 트랜잭션이 만들어진 경우, 커넥션 요청이 많아져 지연
  3. 커넥션이 맺어져도, 이후 요청과 서버에 의한 처리 때문에 지연
  4. 응답을 보내는 것 역시 지연

성능 관련 중요 요소 = HTTP 프로그래머에게 영향을 주는 가장 일반적인 TCP 관련 지연

  1. 핸드셰이크 설정

    • 만약 HTTP 트랜잭션이 아주 큰 데이터를 주고 받지 않는 이상, SYN 핸드셰이크와 SYN + ACK 핸드셰이크가 눈에 띄는 지연 발생시킴.
    • 크기가 작은 HTTP 트랜잭션의 경우 50% 이상의 시간을 TCP를 구성하는데 쓰임
  2. TCP의 편승 확인응답을 위한 확인응답 지연 알고리즘

    확인응답이란? 인터넷 자체가 패킷 전송을 완벽하게 지원하지 않아 TCP는 자체적인 확인응답이 있음. 세그먼트의 수신자는 세그먼트를 온전히 받으면 확인응답 패킷을 발송자에게 반환

    확인응답은 그 크기가 작기 때문에, TCP는 같은 방향으로 송출되는 다른 데이터 패킷에 확인응답을 편승시킴으로써 네트워크를 효율적으로 사용하려고 노력함.

    확인응답 지연 알고리즘? 확인응답을 특정시간 동안 버퍼에 저장한 뒤, 묶어서 보낼 수 있는 다른 데이터 패킷을 찾는 알고리즘. 그래도 편승을 못하면 별도의 패킷으로 전송.

    그러나 HTTP 동작방식은 확인응답이 편승할 가능성을 감소시킴. (요청과 응답 두 가지만 있기 때문)

    즉, 확인응답 지연 기능을 수정하거나 끄면 속도가 좀 더 빨라질 수 있음.

  3. 인터넷의 혼잡을 제어하기 위한 TCP의 느린 시작

    TCP의 데이터 전송속도는 TCP 커넥션이 만들어지고 나서 제일 느림.

    • 시간이 지나면서 속도제한을 품.
    • 이를 통해 인터넷의 급작스러운 부하와 혼잡을 막을 수 있음.
    • TCP가 한번에 전송할 수 있는 패킷의 수를 제한.

    이 기능 때문에 가장 최근에 만들어진 커넥션의 속도가 제일 느림

    따라서, 이미 만들어진 커넥션을 재사용하는 기능이 있음.

  4. 데이터를 한번에 모아 전송하기 위한 네이글 알고리즘

    어떤 크기의 데이터라도 전송하기 위해 TCP는 데이터 스트림 인터페이스를 제공함.

    • 하지만 각 TCP 세그먼트는 40바이트 상당의 플래그와 헤더를 포함하여 전송.
    • 따라서 TCP가 작은 크기의 패킷을 많이 전송하면 네트워크 성능이 크게 떨어짐

    네이글 알고리즘은 최대한 많은 TCP 데이터를 한 개의 덩어리로 합쳐서 보낸다.

    • 다만, 이 알고리즘은 HTTP 성능과 관련해 많은 문제를 일으킴.
    • 따라서 네이글 알고리즘을 비활성화하는 경우도 있다.
  5. TIME_WAIT 지연과 포트 고갈

    • 하나의 TCP 연결이 맺어지고 데이터를 주고받은 후 연결이 완전하게 소멸되는데 최소 60초 이상이 소요
    • TIME_WAIT 상태로 60초 동안 연결을 유지하고 있어야 하기 때문에(=지연) 로컬 포트를 많이 사용
    • 이런 경우 포트가 고갈될 수 있음. 주로 테스트 중에 생기는 문제

HTTP 커넥션 관리

커넥션을 생성하고 최적화하는 HTTP 기술.

먼저 커넥션 헤더에 대해 알아보고, HTTP 커넥션의 최적화 기술을 알아보자.

커넥션 헤더

  • 두 개의 인접한 HTTP 어플리케이션이 현재 맺고 있는 커넥션에만 적용할 옵션을 지정해야 할 수도 있음.
  • HTTP Connection 헤더 필드에 커넥션 토큰을 쉼표로 구분하여 가지고 있고, 그 값들은 다른 커넥션에 전달되지 않음.
  • 커넥션 헤더에는 3가지 종류의 토큰이 전달될 수 있기 때문에 혼란스러울 수도 있다.
    1. HTTP 헤더 필드 명 : 이 커넥션에만 해당되는 헤더들을 나열
    2. 일시적인 토큰 값 : 커넥션에 대한 비표준 옵션
    3. close 값 : 커넥션이 작업이 완료되면 종료되어야 함
  • 커넥션 헤더에 HTTP 헤더 필드 명이 있다면, 이 필드들은 다음 커넥션에 전달되면 안됨.
    • 이를 위해 홉별(hop-by-hop) 헤더 명을 기술.
    • 홉은 각 서버를 의미하며, 다음 홉으로 가기 전 삭제를 해야하는지 알려줌

HTTP 커넥션의 최적화

순차적인 트랜잭션 처리에 의한 지연

  • 3개의 이미지가 있는 웹페이지가 있다고 할 때, 트랜잭션은 총 4개가 필요하다. (html + 이미지 3장)
  • 하나하나를 순차적으로 받으면 한번에 1개씩 이미지가 채워지게 된다. 사용자가 느리다고 판단할 수 있는 부분
  • 따라서 이를 개선하기 위해 크게 4가지의 개선방법이 있다.

언제 커넥션을 끊어야 하는가?

딱히 정의되어 있는 것은 아니나, 책에서 나와 있는 부분만 정리해보았다.

  1. 마음대로
  2. Content-Length의 값이 실제 엔터티의 길이와 맞지 않는 경우
  3. 에러가 없어도 언제든지 끊어질 준비는 해 놔야 함.
  4. 전체 끊기 / 절반 끊기
    1. 단순한 케이스에서는 전체 끊기 가능.

    2. 복잡한 케이스에서는 절반 끊기를 통해 쓰기 에러를 방지.

    3. 우아하게 끊기 : 자신의 출력 채널을 먼저 끊고, 상대방의 출력 채널이 끊기기를 기다리는 것.

      더는 데이터를 전송하지 않을 것이라고 알려주면 커넥션은 리셋의 위험 없이 종료.