NetWork[TCP-2]
HTTP는 TCP 바로 위에 있는 계층이기 떄문에 HTTP 트랜잭션의 성능은 그 아래 계층인 TCP 성능에 영향을 받습니다.
HTTP 트랜잭션 지연
트랜잭션을 처리하는 시간은 클라이언트나 서버가 특정 작업(시간이 오래 걸리는 작업)을 제외하면 처리하는 시간 외에 다른 작업보다 상당히 짧다는 것을 알 수 있습니다.
HTTP 트랜잭션을 지연시키는 원인은 여러가지가 있는데, 이 원인에 대해서 알아보겠습니다.
웹 서버의 IP 주소와 포트 번호를 찾는 시간
해당 URI에 기술되어 있는 호스트에 방문한 적이 없으면, DNS 이름 분석 인프라를 통해 호스트 명을 IP 주소로 변환하는데 시간이 걸립니다.
응답 회신 시간
클라이언트가 서버로 TCP 커넥션 요청을 보내고 응답 회신을 받는데 기다리는 시간이 보통 1~2초로 짧지만, 수백개의 HTTP 트랜잭션이 만들어지면 소요시간은 크게 증가합니다.
데이터 처리 밎 응답
서버는 HTTP 요청을 새로 생성된 TCP 파이프를 통해 데이터를 받는데, 데이터가 도착하면 TCP 커넥션에서 요청메세지를 읽고 처리합니다. 이때 요청 메시지가 전달되고, 서버에 의해 처리되는데 까지 시간이 걸립니다.
또한 서버가 다시 HTTP 응답을 보내는것 또한 시간이 소요됩니다.
이런 TCP 네트워크 지연은 하드웨어 성능, 네트워크 성능 등 여러 요인에 따라 크게 달라집니다.
TCP 커넥션 핸드셰이크 지연
어떤 데이터든 전송을 하기위해서는 TCP 커넥션을 맺어야 하는데, 이때 핸드셰이크가 발생합니다.
- 3way 핸드 셰이크 : TCP 커넥션을 맺기 위한 과정
- 4way 핸드 셰이크 : TCP 커넥션을 끊기 위한 과정
TCP 소프트웨어는 커넥션을 맺기 위한 조건을 맞추기 위해 연속으로 IP 패킷을 교환하는데, 이때 작은 크기의 데이터 전송에 커넥션이 사용된다면 이는 HTTP의 성능을 크게 저하 시킬 수 있습니다.
TCP 커넥션 과정 [사진]
- 클라이언트는 서버에게 TCP 커넥션을 맺기 위해 SYN(커넥션 생성 요청)이라는 플래그를 전송합니다.
- 서버는 커넥션을 받고, SYN + ACK 플래그를 포함한 TCP 패킷을 클라이언트에게 다시 전송합니다.
- 클라이언트는 TCP 커넥션이 맺어지면, 확인 응답 신호를 보냅니다.
아주 큰 데이터가 아닌 평범한 수준의 데이터를 주고 받는 경우에는 커넥션을 맺는 핸드셰이크에서 눈에띄게 지연시간이 발생하는 것을 볼 수 있습니다.
즉, 작은 크기의 HTTP 트랜잭션은 50%이상의 시간을 TCP를 구성하는데 쓴다는 사실을 알 수 있습니다. 이를 TCP 커넥션 핸드셰이크 지연이라고 합니다.
확인 응답 지연
TCP는 성공적인 데이터 전송을 보장하기 위해 자체적인 확인 체계를 가집니다.
TCP 세그먼트는 순번과 데이터 무결성 체그섬을 가지는데, 수신자가 세그먼트를 온전히 받으면 작은 확인응답 패킷을 송신자에게 반환합니다.
이때 확인응답은 그 크기가 매우 작아서 TCP는 같은 방향으로 송출되는 데이터 패킷에 확인응답을 편승 시켜서 전송합니다. 만약에 같은 방향으로 가는 데이터 패킷이 없다면 별도의 패킷을 만들어 전송시킵니다. 이는 확인응답 지연 알고리즘이라고 불립니다.
HTTP 동작 방식은 요청, 응답 두가지 형식으로만 이루어지기 떄문에 확인 응답이 송출 데이터 패킷에 편승할 기회를 감소시킵니다. 이때 확인응답 알고리즘으로 인해 지연이 자주 발생합니다.
TCP 느린 시작
TCP 커넥션은 만들어진지 얼마나 지났냐에 따라 달라집니다.
처음에는 커넥션의 최대 속도를 제한 하지만, 데이터가 성공적으로 전송됨에 따라 제한 속도를 점차 높여 나갑니다. 이를 TCP의 느린시작이라고 불립니다.
간단히 말하면 처음에는 1개의 패킷을 전송할 수 있었지만, 패킷이 성공적으로 전달되는 시점에 송신자는 추가로 2개의 패킷을 더 전송할 수 있는 권한을 얻는다라고 생각하시면 됩니다. 이를 혼잡제어라고 합니다.
네이글 알고리즘, TCP_NODELAY
네이글 알고리즘은 네트워크 효율을 위해서 패킷을 전송하기 전에 많은 양의 TCP 데이터를 한 개의 덩어리로 합치는 알고리즘 입니다.
즉, 세그먼트가 최대 크기가 되지 않으면 버퍼에 저장되었다가 전송하기 충분할 만큼의 패킷이 쌓였을 때 전송하거나, 전송되고나서 확인응답을 기다리던 패킷이 확인응답을 받았을 경우 전송합니다.
다만, 다른 모든 패킷이 확인응답을 받았을 경우에는 최대 크기의 패킷보다 작은 크기의 패킷의 전송을 허락합니다.
하지만 네이글 알고리즘은 여러 문제를 발생시킵니다.
- 불확실한 추가적인 데이터를 기다립니다. ( 시간 지연 )
- 확인응답과 함께 쓰일 경우 형편없이 동작합니다.
- 네이글은 확인응답을 계속 기다리지만, 확인응답은 100~200밀리초 지연시킵니다.
하지만 네이글 알고리즘을 비활성화 시키는 방법 또한 존재합니다.
HTTP 스택에 TCP_NODELAY 파라미터 값을 설정하면 됩니다.
TIME_WAIT 의 누적, 포트 고갈
TIME_WAIT와 포트 고갈은 성능 측정 시에 심각한 성능 저하를 초래합니다. 하지만 실제 상황에서는 문제를 초래하지 않습니다.