4장 커넥션 관리

 

4.1 TCP 커넥션

HTTP 통신은 패킷 교환 네트워크 프로토콜들의 계층화 된 집합인 TCP/IP로 이루어진다.

1) 브라우저가 URL의 호스트명을 추출한다.

2) 브라우저가 이 호스트명에 대한 IP 주소를 찾는다.

3) 브라우저가 포트 번호를 얻는다.

4) 브라우저가 IP주소의 포트번호로 TCP커넥션을 생성한다.

5) 요청 메시지와 응답 메시지를 주고 받은 후 커넥션을 끊는다.

 

4.1.1 신뢰할 수 있는 데이터 전송 통로인 TCP

TCP 커넥션 한 쪽의 바이트들은 반대쪽으로 순서에 맞게 정확히 전달된다.

 

4.1.2 TCP 스트림은 세그먼트로 나뉘어 IP 패킷을 통해 전송된다

HTTP가 메시지를 전송하고자 할 경우, TCP는 세그먼트 단위로 데이터 스트림을 잘게 나누고 세그먼트를 IP 패킷에 담아 인터넷을 통해 데이터를 전달한다. IP 패킷은 IP패킷 헤더, TCP 세그먼트헤더, TCP 데이터 조각으로 이루어진다. IP헤더는 발신지와 목적지의 IP주소 등을 포함하여 TCP 세그먼트 헤더는 TCP 포트 번호와 TCP 제어 플래그, 데이터 순서와 무결성을 검사하는 숫자 값을 포함한다.

 

4.1.3 TCP 커넥션 유지하기

IP 주소는 해당 컴퓨터에 연결되고 포트 번호는 해당 애플리케이션으로 연결된다. 한 컴퓨터는 <발신지 IP주소, 발신지 포트, 수신지 IP주소, 수신지 포트>로 구분되는 TCP 커넥션을 여러개 형성한다.

 

4.1.4 TCP 소켓 프로그래밍

운영체제는 TCP 커넥션의 생성과 관련된 여러 기능을 제공한다.

 

4.2 TCP의 성능에 대한 고려

HTTPTCP 바로 위에 있는 계층이기 때문에 HTTP 트랜잭션의 성능은 그 아래 계층인 TCP 성능에 영향을 받는다.

 

4.2.1 HTTP 트랜잭션 지연

트랜잭션의 처리 시작은 TCP 커넥션을 설정하고 요청을 전송하고 응답을 보내는 것에 비하면 상당히 짧다. 클라이언트가 서버가 너무 많은 데이터를 내려 받거나 복잡하고 동적인 자원들을 실행하지 않는 한 대부분의 HTTP 지연은 TCP 네트워크 지연 때문에 발생한다.

 

4.2.2 성능 관련 중요 요소

TCP 관련 지연에는 TCP 커넥션의 핸드셰이크 설정, 인터넷 혼잡을 제어하기 위한 TCP의 느린 시작, 데이터를 모아 한 번에 전송하기 위한 네이클 알고리즘, TCP의 편승 확인응답을 위한 확인 응답 지연 알고리즘, TIME_WAIT 지연과 포트 고갈이 있다.

 

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

어떤 데이터를 전송하든 새로운 TCP 커넥션을 열 때면, TCP 소프트웨어는 커넥션을 맺기 위한 조건을 맞추기 위해 연속으로 IP 패킷을 교환한다. 이때 작은 크기의 데이터 전송에 커넥션이 사용된다면 이러한 패킷 교환이 HTTP 성능을 크게 저하시킨다. 트랜잭션의 과반 이상의 시간을 TCP를 구성하는데 사용하는게 될 수 있다.

 

4.2.4 확인 응답 지연

TCP 세그먼트는 순번과 데이터 무결성 체크섬을 가진다. 각 세그먼트의 수신자는 세그먼트를 온전히 받으면 작은 확인 응답 패킷을 송신자에게 반환한다. 만약 송신자가 확인 응답 메시지를 받지 못하면 패킷이 파기되었거나 오류가 있는 것으로 판단한다. 이때 HTTP는 효율성을 위해 몇몇 확인 응답 패킷을 버퍼에 담아두었다 같은 방향으로 송출되는 데이터 패킷에 편승시킨다. 그런데 같은 방향으로 송출되는 데이터 패킷이 많지 않아 지연이 발생할 수 있다.

 

4.2.5 TCP 느린 시작

TCP의 데이터 전송 속도는 TCP 커넥션이 만들어진지 얼마나 지났는지에 따라 달라진다. TCP는 처음엔 커넥션의 최대 속도를 제한하고 데이터가 성공적으로 전송됨에 따라서 속도 제한을 높여나간다. 따라서 새로운 커넥션은 어느 정도 데이터를 주고 받은 튜닝된 커넥션보다 느리다.

 

4.2.6 네이글 알고리즘과 TCP_NODELAY

네이글 알고리즘은 네트워크 효율을 위해 패킷을 전송하기 전에 많은 양의 TCP 데이터를 한 개의 덩어리로 합친다. 네이글 알고리즘은 세그먼트가 최대 크기가 되지 않으면 전송을 하지 않는다. (다만 모든 패킷이 확인 응답을 받았을 경우 작은 패킷도 전송할 수 있다.) 그러나 이 경우 크기가 작은 HTTP 패킷은 계속해서 불확실한 추가적인 데이터를 기다리며 지연된다. , 네이글 알고리즘과 확인 응답 지연이 맞물려 형편없이 동착할 수 있다.

 

4.2.7 TIME_WAIT의 누적과 포트 고갈

//

 

4.3 HTTP 커넥션 관리

 

4.3.1 흔히 잘못 이해하는 Connection 헤더

HTTP 메시지는 클라이언트에서 서버까지 중개 서버들을 거치면서 전달된다. 어떤 경우에는 두 개의 인접한 HTTP 애플리케이션이 현재 맺고 있는 커넥션에만 적용될 옵션을 지정해야 할 때가 있다. HTTP Connection 헤더 필드는 커넥션 토큰을 쉼표로 구분하여 가지며 그 값들은 다른 커넥션에 전달되지 않는다.

 

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

3개의 이미지가 있는 웹 페이지를 사용자에게 보여주려면 해당 HTML을 받기 위한 커넥션과 이미지를 보여주는 세 개의 커넥션이 맺어질 것이다. 이때 느린 시작 지연과 함께 커넥션을 맺는데 발생하는 지연이 발생한다. 한편 하나의 이미지를 내려 받는 중에는 웹 페이지 나머지 공간에 아무런 변화가 없어 느껴지는 심리적 지연도 있다. , 특정 브라우저는 이미지들을 화면에 배치하려면 크기를 알아야 하기 때문에 모든 이미지를 내려받기 전까지 사용자에게 텅 빈 화면만을 보여줄 것이다.

 

4.4 병렬 커넥션

HTTP는 클라이언트가 여러개의 커넥션을 맺음으로써 여러 개의 트랜잭션을 병렬로 처리할 수 있게 한다.

 

4.4.1 병렬 커넥션은 페이지를 더 빠르게 내려받는다.

단일 커넥션의 대역폭 제한과 커넥션이 동작하고 있지 않는 시간을 활용하면, 객체가 여러개 있는 웹페이지를 더 빠르게 내려 받을 수 있을 것이다. , 클라이언트의 인터넷 대역폭을 한 개의 커넥션이 다 써버리는게 아니라면

4.5.나머지 객체를 내려받는 데에 나머지 대역폭을 사용할 수 있다.

 

4.4.2 병렬 커넥션이 항상 더 빠르지는 않다.

클라이언트의 네트워크 대역폭이 좁을 때는 대부분의 시간을 데이터를 전송하는 데만 쓸 것이다. 여러 개의 객체를 병렬로 내려받는 경우 이 제한된 대역폭 내에서 각 객체를 전송받는 것은 느리기 때문에 성능상 장점은 거의 없어진다. 또한 다수의 커넥션은 메모리를 많이 서버하고 자체적인 성능 문제를 발생시키기도 한다.

 

4.4.3 병렬 커넥션은 더 빠르게 느껴질 수 있다.

병렬 커넥션이 페이지를 항상 더 빠르게 로드하는 것은 아니지만 화면에 여러 개의 객체가 동시에 보이면서 내려받고 있는 상황을 볼 수 있기 때문에 사용자는 더 빠르게 내려받고 있는 것처럼 느낄 수 있다.

 

4.5 지속 커넥션

웹 클라이언트는 보통 같은 사이트에 여러 개의 커넥션을 맺는다. 따라서 처리가 완료된 후에도 TCP 커넥션을 유지하여 앞으로 있을 HTTP 요청에 재사용하는 것은 효율적인 커넥션이 될 수 있다. 이를 지속 커넥션이라고 한다.

 

4.5.1 지속 커넥션 vs 병렬 커넥션

병렬 커넥션과 다르게 커넥션을 맺기 위한 사전 작업을 줄여주고 튜닝된 커넥션을 유지한다.

 

4.5.2 HTTP/1.0+Keep-Alive 커넥션

HTTP/1.0 브라우저는 keep-alive라는 지속 커넥션을 지원한다. 이는 커넥션을 맺고 끝는데 필요한 작업이 생략되어 시간이 단축된다.

 

4.5.3 Keep-Alive 동작

HTTP/1.0 keep-alive 커넥션을 구현한 클라이언트는 커넥션을 유지하기 위해서 요청에 ‘Connection:Keep-Alive’ 헤더를 포함시킨다. (keep-alive는 사용하지 않기로 결정되어 HTTP/1.1 명세에서 빠졌지만 아직도 브라우저와 서버 간에 이것이 널리 사용하고 있기 때문에 HTTP 애플리케이션은 그것을 처리할 수 있게 개발해야 한다.)

 

4.5.4 Keep-Alive 옵션

keep-alive 헤더는 커넥션을 유지하기를 바라는 요청일 뿐으로 응답자가 무조건 이를 따를 필요는 없다.

 

4.5.5 Keep-Alive 커넥션 제한과 규칙

 

4.5.6 Keep-Alive와 멍청한 프락시

1) 클라이언트는 프락시에 keep-alive 헤더와 함께 메시지를 보내고 (프락시와) 커넥션을 유지하기를 요청한다.

2) 멍청한 프락시는 요청받은 keep-alive 헤더를 이해하지 못하고 서버에 그대로 전달한다.

3) 서버는 프락시가 커넥션을 유지하자고 요청한 것으로 잘못 판단하고 keep-alive헤더를 포함한 메시지를 클라이언트에게 전달한다.

4) 클라이언트는 프락시가 커넥션을 유지하는 것에 동의했다고 추정한다.

5) 프락시는 서버가 커넥션을 끊기를 기다리지만 서버는 커넥션을 끊지 않는다.

6) 클라이언트는 프락시에게 다음 요청을 보내지만, 프락시는 같은 커넥션에서 다른 요청이 오는 경우는 예상하지 못하여 무시되고 브라우저는 자신이나 서버가 타임아웃이 나서 끊길 때까지 기다린다.

프락시는 Connection : keep-alive 헤더를 절대 전달해서는 안 된다.

 

4.5.7 Proxy-Connection 살펴보기

멍청한 프락시 문제를 해결하기 위해서 Connection 헤더 대신 Proxy-Connection 확장 헤더를 프락시에게 전달하는 방법이 있다. 프락시가 Proxy-Connection 헤더를 무조건 전달하더라도 웹서버는 그것을 무시하기 때문에 별 문제가 되지 않는다. 하지만 영리한 프락시라면 Proxy-Connection 헤더를 Connection 헤더로 바꿈으로써 원하던 효과를 얻게 될 것이다. 이 방식은 클라이언트와 서버 사이에 한 개의 프락시만 있는 경우에만 동작한다. 멍청한 프락시 양옆에 영리한 프락시가 있다면 잘못된 헤더를 또 만들어낸다.

 

4.5.8 HTTP/1.1의 지속 커넥션

HTTP/1.1에서는 기본적으로 모든 커넥션을 지속 커넥션으로 취급하며 트랜잭션을 끊으려면 Connection : close 헤더를 명시해야 한다. (물론 자발적으로 클라이언트와 서버는 언제든지 끊을 수 있다.)

 

4.6 파이프라인 커넥션

여러 가지 요청은 응답이 도착하기 전까지 큐에 쌓인다. 첫 번째 요청이 네트워크를 통해 서버로 전달되면 거기에 이어 두 번째와 세 번째 요청이 전달될 수 있다. 이는 네트워크상 왕복으로 인한 시간을 줄인다.

 

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

커넥션 관리에는 명확한 기준이 없다.

 

4.7.1 ‘마음대로커넥션 끊기

보통 커넥션은 메시지를 다 보낸 다음 끊지만, 에러가 있는 상황에서는 헤더의 중간이나 다른 엉뚱한 곳에서 끊길 수 있다. 또 지속 커넥션이 일정시간 요청을 전송하지 않은 임의로 커넥션을 끊을 수 있다.

 

4.7.2 Content-LengthTruncation

 

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

커넥션은 에러가 없더라도 언제든지 끊을 수 있다. HTTP 애플리케이션은 예상치 못하게 커넥션이 끊어졌을 때에 적절히 대응할 수 있는 준비가 되어 있어야 한다. 클라이언트가 트랜잭션 수행 중 커넥션이 끊기면 커넥션을 다시 맺고 한 번 더 전송을 시도해야 한다. 이때 요청 데이터가 전송되었는데 응답이 오기 전 커넥션이 끊기면 클라이언트는 실제로 얼만큼 요청이 처리되었는지 전혀 알 수 없으므로 요청이 여러번 중복되지 않도록 주의해야한다.

 

* 한 번 혹은 여러번 실행됐는지에 상관없이 같은 결과를 반환한다면 그 트랜잭션을 멱등이라 한다.

 

4.7.4 우아한 커넥션 끊기

- 전체 끊기 : 입력과 출력 채널을 모두 끊는다.

- 절반 끊기 : 입력 출력 둘 중 하나의 채널을 끊는다. 출력 채널을 끊는 것이 더 안전하다. 만약 클라이언트가 이미 끊긴 입력 채널에 데이터를 전송하면, 서버는 에러 메시지를 보내고 대부분의 운영체제는 이것을 심각한 에러로 취급하여 버퍼에 저장된 읽히지 않은 데이터를 모두 삭제한다. (클라이언트가? 서버가?)

일반적으로 애플리케이션이 우아한 커넥션 끊기를 구현하는 것은 애플리케이션 자신의 출력 채널을 먼저 끊고 다른 쪽에 있는 기기의 출력 채널이 끊기는 것을 기다리는 것이다.

'HTTP' 카테고리의 다른 글

[HTTP 완벽 가이드] 2-1. HTTP 메시지  (0) 2022.06.29
[HTTP 완벽 가이드] 1-2. URL과 리소스  (0) 2022.06.22
[HTTP 완벽 가이드] 1-1. HTTP 개관  (0) 2022.06.16

서적  'HTTP 완벽 가이드 - 웹은 어떻게 동작하는가'를 요약 정리한 내용입니다.

 

1HTTP 개관

 

1.1 HTTP:인터넷의 멀티미디어 배달부

 

1.2 웹 클라이언트와 서버

클라이언트(웹 브라우저)는 서버에게 HTTP 요청을 보내고 서버는 요청된 데이터를 HTTP 응답으로 돌려준다.

 

1.3 리소스

리소스는 웹에 콘텐츠를 제공하는 모든 것들을 말한다.

예시) 텍스트 파일, HTML 파일, 워드 파일, 이미지 파일 등 정적 파일과 웹 캠, 주식 거래, 전자상거래 게이트웨이 등 동적 파일

 

1.3.1 미디어 타입

웹 서버는 모든 HTTP 객체 데이터에 MIME 타입을 붙인다. 웹 브라우저는 서버로부터 객체를 돌려받을 때, 다룰 수 있는 객체인지 MIME 타입을 통해 확인한다. MIME 타입은 주 타입과 부 타입으로 이루어진 문자열 라벨이다.

예시) HTML text/html, plain ASCII-text/plain, JPEG-image/jpeg

 

1.3.2 URI

웹 서버 리소스는 각자 이름을 갖고 있는데 이를 통합 자원 식별자, URI(unifrm resource identifier)라 한다. URI의 종류에는 URNURL이 있다.

 

1.3.3 URL

통합 자원 지시자(Uniform resource locator, URL)는 리소스 식별자의 가장 흔한 형태로, 특정 서버의 한 리소스에 대한 구체적인 위치를 서술하며 어떻게 접근할 수 있는지도 나타낸다.

예시) (https://) + (postfiles.pstatic.net) + (/MjAyMjAxMjJfMjAw)

첫 번째 부분은 스킴이라고 하는데, 리소스에 접근하기 위해 사용되는 프로토콜을 서술한다.

두 번째 부분은 서버의 인터넷 주소를 제공한다.

마지막은 웹 서버의 리소스를 가리킨다.

 

1.3.4 URN

유니폼 리소스 이름(Uniform Resource Name, URN)은 콘텐츠를 이루는 한 리소스에 대해 그 리소스의 위치에 영향 받지 않는 이름 역할을 한다. URN은 위치 독립적이어서 이름을 변하지 않게 유지하는 한, 리소스를 여기저기로 옮기더라도 문제없이 동작하며 여러 종류의 네트워크 접속 프로토콜로 접근해도 문제없다.

 

1.4 트랜잭션

HTTP 트랜잭션은 클라이언트가 서버로 보내는 요청 명령과 서버가 클라이언트에게 돌려주는 응답 결과로 구성되어 있다.

 

1.4.1 메서드 (요청 명령)

HTTPHTTP 메서드라고 불리는 여러 가지 종류의 요청 명령을 지원한다. 모든 HTTP 요청 메시지는 한 개의 메서드를 갖는다. 메서드는 서버에게 어떤 동작이 취해져야 하는지 말해준다.

예시)

GET-서버에서 클라이언트로 지정한 리소스를 보내라

PUT-클라이언트에서 서버로 보낸 데이터를 지정한 이름의 리소스로 저장하라

DELETE-지정한 리소스를 서버에서 삭제하라

POST-클라이언트 데이터를 서버 게이트웨이 애플리케이션으로 보내라

HEAD-지정한 리소스에 대한 응답에서 HTTP 헤더 부분만 보내라

 

1.4.2 상태 코드 (응답 결과)

모든 HTTP 응답 메시지는 상태 코드와 함께 반환된다. 상태 코드는 클라리언트에게 요청이 성공했는지 추가 조치가 필요한지 알려주며, 숫자 상태 코드에 더해 텍스트로 된 사유 구절도 함께 보낸다.

 

1.4.3 웹페이지는 여러 객체로 이루어질 수 있다.

하나의 작업을 수행하기 위해서는 여러 HTTP 트랜잭션을 수행한다. 예를 들어 페이지 레이아웃을 서술하는 HTML 뼈대를 한 번의 트랜잭션으로 가져온 뒤 이미지, 그래픽 등을 가져오는 HTTP 트랜잭션을 추가로 수행한다.

 

1.5 메시지

HTTP 요청 및 응답 메시지는 시작줄, 헤더, 본문으로 이루어진다.

시작줄 요청은 무엇을 해야 하는지, 응답은 무슨 일이 일어났는지 나타낸다. 상태코드와 사유 구절, HTTP 버전 등이 여기에 포함된다.

헤더 요청의 경우 호스트 정보와 무엇을 받아올 것인지, 응답의 경우 서버 정보와 내용의 길이와 타입 등이 해당된다.

본문 데이터를 실어 보내거나 반환한다.

 

1.6 TCP 커넥션

TCP란 전송 제어 프로토콜 (Transmissoin Control Protocol)을 의미한다.

 

1.6.1 TCP/IP

HTTP는 애플리케이션 계층 프로토콜로, 네트워크 통신의 핵심적인 세부사항은 신경 쓰지 않으며 이를 TCP/IP에게 맡긴다. TCP/IPTCPIP가 층을 이루는 패킷 교환 네트워크 프로토콜의 집합이다. 이는 각 네트워크와 하드웨어의 특성을 숨기고 어떤 컴퓨터나 네트워크든 서로 신뢰성 있는 의사소통을 하게 해준다. TCP 커넥션이 맺어지면 클라이언트와 서버 컴퓨터 간 교환되는 메시지가 없어지거나, 손상 되거나, 순서가 뒤바뀌어 수신되는 일은 결코 없다.

 

1.6.2 접속, IP주소, 포트번호

TCP/IP 커넥션을 맺기 위해서는 IP 주소와 포트번호를 이용해 클라이언트와 서버 사이에 커넥션을 맺어야 한다. IP주소와 포트번호는 URL을 이용하여 알 수 있다. URL에는 IP주소와 포트번호가 있으며, IP 주소는 문자로 된 도메인 이름으로 대체하여 사용하기도 한다. (일종의 별명)

 

1.7 프로토콜 버전

HTTP 0.9, HTTP 1.0, HTTP 1.1, HTTP 2.0

 

1.8 웹의 구성요소

인터넷과 상호작용 할 수 있는 웹 애플리케이션은 많다.

(예시) 프락시, 캐시, 게이트웨이, 터널

 

1.8.1 프락시

프락시는 클라이언트와 서버 사이에 위치한 HTTP 중개자이다. 클라이언트의 HTTP 요청을 수정하고 서버에 전달하며, 바이러스를 검출하거나 성인 콘텐츠를 차단하는 등 요청과 응답을 필터링한다.

 

1.8.2 캐시

캐시는 많이 찾는 웹페이지를 클라이언트 가까이에 보관하는 HTTP 창고이다. 웹캐시와 캐시 프락시는 자신을 거쳐가는 문서들 중 자주 찾는 것의 사본을 저장하는 HTTP 프락시 서버이다. 클라이언트는 웹 서버보다 근처의 캐시에서 훨신 더 빨리 문서를 다운 받을 수 있다.

 

1.8.3. 게이트웨이

게이트웨이는 다른 애플리케이션과 연결된 특별한 웹서버이다. 게이트웨이는 다른 서버들의 중개자로 동작하는데, 주로 HTTP 트래픽을 다른 프로토콜로 변환하기 위해 사용된다. 예컨대 HTTP/FTP 게이트웨이는 FTP URI에 대한 HTTP 요청을 받아들인 뒤, FRP 프로토콜을 이용해 문서를 가져온다.

 

1.8.4. 터널

터널은 단순히 HTTP 통신을 전달하기만 하는 프락시이다. 터널은 두 커넥션 사이에서 날 데이터를 열어보지 않고 그대로 전달한다. HTTP 터널은 주로 비 HTTP 데이터를 하나 이상의 HTTP 연결을 통해 그대로 전송해줄 때 사용한다.

 

1.8.5 에이전트

사용자 에이전트는 사용자를 위해 HTTP 요청을 만들어주는 클라이언트 프로그램이다. HTTP 요청을 만들어주는 클라이언트 프로그램은 모두 HTTP 에이전트이며 웹 브라우저도 여기에 속한다.

 

+ Recent posts