대부분의 HTTP 네트워크 지연은 TCP 네트워크 지연 때문에 발생한다.
TCP는 같은 방향으로 송출되는 데이터 패킷에 확인응답을 편승시킨다.
TCP는 송출 데이터 패킷과 확인응답을 하나로 묶음으로써 네트워크를 좀 더 효율적으로 사용한다
확인응답 지연은 송출할 확인응답을 특정 시간 동안 버퍼에 저장해두고, 확인응답을 편승시키기 위한 송출 데이터 패킷을 찾는다
요청/응답 두가지 형식으로만 동작하는 HTTP는 송출 데이터 패킷에 확인 응답을 편승할 기회를 감소시킨다
네트워크 혼잡 제어를 위해 TCP는 Congestion Window Size를 제어하면서 전송한다.
처음부터 데이터를 무작정 많이 보내지 않는다.
이 혼잡제어 기능 때문에, 새로운 커넥션은 이미 어느정도 데이터를 주고받은 튜닝된 커넥션보다 느리다.
튜닝된 커넥션이 더 빠르기 때문에, HTTP는 이미 존재하는 커넥션을 재사용하는 기능이 있다.
HTTP 트랜잭션을 처리하기 위해 TCP 커넥션을 맺고 끊고, 맺고 끊고하는 과정은 비효율적이다.
HTTP 성능을 향상시키기 위한 커넥션 관리를 아래에서 알아보자
Connection 헤더는 홉별(hop by bop)헤더이다. 오직 한 개의 전송 링크에만 적용되며, 다음 서버로는 전달되어서는 안됨.
HTTP 메시지는 클라이언트에서 서버까지 중개 서버들을 하나씩 거치면서 전달된다.
두 개의 인접한 HTTP 어플리케이션이 현재 맺고 있는 커넥션에만 적용될 옵션을 지정해야 할 때가 있다. 그 값들은 다른 커넥션에 전달되지 않아야 한다.
Connection:close
라고 명시할 수 있다.Connection
헤더에는 세가지 종류의 토큰이 전달될 수 있다.
HTTP 애플리케이션은 Connection 헤더와 함께 메시지를 전달받으면, 수신자는 송신자에게서 온 요청에 기술되어있는 모든 옵션을 적용
그리고 다음 홉에 메시지를 전달하기 전에 Connection 헤더와 헤더에 기술되어 있던 모든 헤더를 삭제한다.
여러개의 TCP 커넥션을 통한 동시 HTTP 요청하는 방식이다
일반적으로 병렬적으로 처리하는 것이 좋긴하지만, 항상 더 빠른것은 아니다.
클라이언트 대역폭이 좁을 때 대부분의 시간을 데이터를 전송하는데만 사용할 수 있다.
또한 다수의 커넥션은 메모리를 많이 소모하고 자체적인 성능 문제를 발생한다.
뿐만 아니라, 서버는 다른 여러 사용자의 요청도 함께 처리해야 하기 때문에 일반적으로 수백개의 커넥션을 허용하지 않는다.
브라우저는 실제로 병렬 커넥션을 사용하지만 적은 수(최신 브라우저의 경우 6~8)의 병렬 커넥션만을 허용한다.
서버는 특정 클라이언트로부터 과도한 수의 커넥션이 맺어졌을 경우, 그것을 임의로 끊어버릴 수 있다.
TCP Syn Flooding
커넥션을 맺고 끊는 데서 발생하는 지연을 제거하기 위한 TCP 커넥션 재활용하는 방식이다.
위의 장점을 가지고 있지만, 지속 커넥션을 잘못 관리할 경우, 계속 연결된 상태로 수많은 커넥션이 쌓이게 될 수 있다.
이는 클라이언트와 서버의 불필요한 리소스 낭비를 유발한다.
지속 커넥션 + 병렬 커넥션을 함께 사용할 때 가장 효과적이다.
오늘날 많은 웹 어플리케이션은 적은 수의 병렬 커넥션만을 맺고 그것을 유지한다.
두가지 지속 커넥션 타입이 있다.
keep-alive
커넥션keep-alive 커넥션을 구현한 클라이언트는 커넥션을 유지하기 위해서 Connection:Keep-Alive
헤더를 포함시킨다.
이 요청을 받은 서버는 그 다음 요청도 이 커넥션을 통해 받고자 한다면, 응답 메시지에 같은 헤더를 포함시켜 응답한다.
헤더가 없다면, 클라이언트는 서버가 keep-alive를 지원하지 않으며, 응답 메시지가 전송되고 나면 서버 커넥션을 끊을 것이락 추정한다.
요약하면, keep-alive 헤더는 커넥션을 유지하기를 바라는 요청일 뿐이다. 클라이언트나 서버는 커넥션 헤더를 받았다고 해서 그것을 따를 필요는 없다.또한, 언제든지 커넥션을 끊을 수 있다.
프록시와 게이트웨이는 메시지를 전달하거나 캐시에 넣기 전에 Connection 헤더에 명시된 모든 헤더 필드와 Connection 헤더를 제거해야 한다.
Connection
헤더 대신 비표준인 Proxy-Connection
확장 헤더를 프록시에게 전달한다.Proxy-Connection
확장 헤더를 전달하더라도 웹 서버는 그것을 무시하기 때문에 별 문제가 되지 않는다.Connection:close
헤더를 명시하면 된다.TCP 커넥션은 양방향이다.
전체 끊기 , 절반 끊기