4장 커넥션 관리

 

4.1.3 TCP 커넥션 유지하기

TCP 커넥션은 네가지 값으로 식별한다.
- 발신지 IP 주소
- 발신지 포트
- 수신지 IP 주소,
- 수신지 포트

이 네가지 값으로 유일한 커넥션을 생성한다.


4.2.3 TCP 커넥션 핸드셰이크 지연

1. SYN 이라는 플래그를 가진 작은 TCP 패킷을 서버에 전송(커넥션 생성 요청)
2. SYN과 ACK 플래그를 포함한 TCP 패킷을 클라이언트에 전송
3. 서버에게 ACK 전송

4.2.4 확인응답(ACK) 지연

확인응답은 그 크기가 작기 때문에, 같은 방향으로 송출되는 데이터 패킷에 확인 응답을 편승시킨다.
근데 막상 편승할 패킷을 찾으려고 하면 없을 수도 있기 때문에 이 알고리즘으로 인한 지연이 자주 발생한다.

그래서 이 기능을 수정하거나 비활성화 할 수 있다.

4.2.5 TCP 느린 시작(slow start)
처음엔 커넥션의 최대 속도를 제한하고 데이터가 성공적으로 전송됨에 따라서 속도 제한을 높여나간다.
1->2->4->8


4.2.7 TIME_WAIT의 누적과 포트 고갈
특정 커넥션이 생성되고 닫힌 다음, 그와 같은 IP주소와 포트 번호를 가지는 커넥션이 2분 이내에 또 생성되는 것을 막아준다.


4.3.2 순차적인 트랜잭션 처리에 의한 지연
- 병렬 커넥션
여러 개의 TCP 커넥션을 통한 동시 HTTP 요청
너무 많은 커넥션이 생성되면 서버의 성능을 크게 떨어뜨린다.
서버는 커넥션수가 많아지면 임의로 끊어버릴 수 있음.
전송속도가 느리다면 병렬 커넥션은 사용하지 않는게 좋다.

병렬 커넥션의 단점 : 각 트랜잭션마다 새로운 커넥션을 맺고 끊기 때문에 시간과 대역폭이 소요됨.
각각의 새로운 커넥션은 TCP 느린 시작 때문에 성능이 떨어진다.


- 지속 커넥션
커넥션을 맺고 끊는 데서 발생하는 지연을 제거하기 위한 TCP 커넥션의 재활용
처리가 완료된 후에도 계속 연결상태를 유지.
병렬 커넥션 수에는 제한이 있다.

지속 커넥션은 병렬 커넥션과 함께 사용될 때에 가장 효과적이다.


- 파이프라인 커넥션
공유 TCP 커넥션을 통한 병렬 HTTP 요청


- 다중 커넥션
요청과 응답들에 대한 중재(실험적인 기술이다)


4.5.2 HTTP/1.0+의 Keep-Alive 커넥션
커넥션을 맺고 끊는데 필요한 작업이 없어서 시간이 단축된다.

4.5.3 Keep-Alive 동작

클라이언트는 커넥션을 유지하기 위해 요청에 Connection: Keep-Alive 헤더를 포함시킨다.
이 요청을 받은 서버는 그 다음 요청도 이 커넥션을 통해 받고자 한다면, 응답 메세지에 같은 헤더를
포함시켜 응답한다.

4.5.4 Keep-Alive 옵션
클라이언트나 서버가 keep-alive 요청을 받았다고 해서 무조건 그것을 따를 필요는 없다.

Keep-Alive 헤더 사용은 선택 사항이지만, Connection: Keep-Alive 헤더가 있을때만 사용할 수 있다.

ex)
Connection: Keep-Alive
Keep-Alive: max=5, timeout=120


4.5.8 HTTP/1.1의 지속 커넥션

HTTP/1.1의 지속 커넥션은 기본으로 활성화 되어 있음.
별도 설정하지 않는 이상 모든 커넥션을 지속 커넥션으로 취급한다.
커넥션을 끊으려면 Connection: close 헤더를 명시해야 한다.


4.5.9 지속 커넥션의 제한과 규칙

- 클라이언트가 요청에 Connection: close 헤더를 포함해 보냈으면,
클라이언트는 그 커넥션으로 추가적인 요청을 보낼 수 없다.

- 클라이언트가 해당 커넥션으로 추가적인 요청을 보내지 않을 것이라면,
마지막 요청에 Connection: close 헤더를 보내야 한다.

- 커넥션에 있는 모든 메세지가 자신의 길이 정보를 정확히 가지고 있을 때에만 커넥션을 지속시킬 수 있다.
(길이가 없으면 각 메세지의 끝이 구분이 안 되니까)

- HTTP/1.1 프록시는 클라이언트와 서버 각각에 대해 별도의 지속 커넥션을 맺고 관리해야 한다.
(프록시는 중간에 존재하므로 2개의 커넥션을 관리)

- HTTP/1.1 애플리케이션은 중간에 끊어지는 커넥션을 복구할 수 있어야만 한다.
클라이언트는 다시 보내도 문제가 없는 요청이라면 가능한 다시 보내야 한다.


4.6 파이프라인 커넥션

HTTP 파이프라이닝은 먼저 보낸 요청의 응답이 없어도 다음 요청을 병렬적으로 수신자 측에 전송하는 기술이다.

4.7 커넥션 끊기에 대한 미스터리

커넥션 관리(특히 언제 어떻게 커넥션을 끊는가)에는 명확한 기준이 없다.

4.7.1 마음대로 커넥션 끊기
어떠한 HTTP 클라이언트, 서버, 혹은 프락시든 언제든지 TCP 전송 커넥션을 끊을 수 있다.

4.7.2 Content-Length와 Truncation
각 HTTP 응답은 본문의 정확한 크기 값을 가지는 Content-Length 헤더를 가지고 있어야 한다.

클라이언트나 프락시가 커넥션이 끊어졌다는 HTTP 응답을 받은 후, 실제 전달된 엔티티의 길이와 Content-Length
의 값이 일치하지 않거나 Content-Length 자체가 존재하지 않으면 수신자는 데이터의 정확한 길이를 서버에게 물어봐야 한다.

4.7.3 커넥션 끊기의 허용, 재시도, 멱등성

중간에 예상치 못하게 커넥션이 끊어졌을 때에, 클라이언트는 멱등한 메서드들을 재요청한다.
(멱등 : 여러번 실행되었는지에 상관 없이 같은 결과를 반복하는 경우를 의미)
POST와 같이 멱등이 아닌 요청은 파이프라인을 통해 요청하면 안 된다.
비멱등인 요청을 다시 보내야 한다면, 이전 요청에 대한 응답을 받을 때까지 기다려야 한다.

4.7.4 우아한 커넥션 끊기

일반적으로 애플리케이션이 우아한 커넥션 끊기를 구현하는 것은
애플리케이션 자신의 출력 채널을 먼저 끊고 다른 쪽에 있는 기기의 출력 채널에 끊기는 것을 기다리는 것이다.
양쪽에서 더는 데이터를 전송하지 않을 것이라고 알려주면(출력 채널의 커넥션을 끊는것), 커넥션은 리셋의 위험 없이 온전히 종료된다.

+ Recent posts