여기서 정리할 것은 제가 공부하면서 TCP Connection의 방식이 너무나도 말이 안되게 비효율적이라서 이 부분을 도대체 어떻게 해결하였는지 궁금해서 찾아본 내용을 토대로 정리한 것입니다.
일단, 출처부터 말씀을 드리자면,
이렇게 참고를 했습니다.
먼저 제가 학습하면서 배웠던 동작을 적어가도록 하겠습니다. 여기서는 HTTP 통신을 기준으로 얘기를 하겠습니다.
기본적으로 TCP든 UDP든 소켓을 생성하면서 연결을 취합니다.
여기서는 TCP에 관해서 얘기를 다루도록 하겠습니다.
서버가 소켓을 생성하고 bind()함수를 통해서 커널에 올려둠으로써 클라이언트로 부터 오는 소켓을 받을 준비를 해놓고 클라이언트가 소켓을 보내오면 확인하는 과정을 통해서 연결이 된 소켓을 보내고 클라이언트는 이것을 받고 필요한 자료를 요구함으로써 서로의 연결이 완료됩니다.
이 과정을 3 방향 핸드셰이크라고 합니다.
근데 여기서 문제점은 서로의 연결을 맺는 호스트끼리의 거리가 매우 먼 경우에 이 과정을 통한 지연이 상당히 많이 발생한다는 문제점이 발생합니다.
이것은 병렬 커넥션을 통해서 문제점을 해결할 수 있습니다.
병렬 커넥션의 경우 여러 개(보통 4개 이하)의 커넥션을 맺으면서 서버와 동시에 커넥션을 맺으면서 시간 지연을 줄입니다.
이렇게 함으로써 클라이언트와 서버 사이의 커넥션을 맺는 작업으로 인한 지연을 줄였습니다.
여기서 생기는 의문점은 "그렇다면 이것이 종단간의 커넥션에만 해당하는 것이냐"입니다.
기본적으로 클라이언트와 서버가 데이터를 주고 받기 위해선 중간에 프록시 서버, 캐시 서버 등 굉장히 많은 중간 매개체가 존재합니다.
이러한 중간 매개체와 전부 커넥션이 맺어질 경우에 아무리 커넥션 자체의 성능을 올려준다고 해도 지연은 피할 수 없을 것입니다.
하지만, 모든 중간 서버들은 각각 TCP 커넥션을 맺습니다.
생각해 봅시다. 클라이언트와 서버 사이에 존재하는 모든 중간 매개체와 세방향 핸드셰이크를 통해 커넥션을 맺는다고 상상해 봅시다. 이 방식은 정말 너무나도 비효율적입니다.
이 부분에 대해서 지속 커넥션의 기능을 통해서 문제를 어느 정도 해결해 줄 수 있습니다.
지속 커넥션의 경우 기존에 맺어놨던 커넥션을 재활용함으로써 TCP에서 혼잡 제어를 위해 존재하는 튜닝 작업을 유지한 채로 데이터를 보내기 때문에 효율성을 높여줍니다.
다음과 같은 상황을 예로 들어봅시다.
만약 naver.com을 들어가서 네이버 서버와 TCP 커넥션을 맺고 나서, 이후에 다른 브라우저인 google.com을 들어가면 이전의 커넥션을 재활용 할 수 있을까요?
먼저, HTTP 1.1에서는 "Connection:keep-alive" 옵션을 사용하여 한 번의 연결로 여러 요청과 응답을 처리 할 수 있게 되어, 동일한 서버에 대해서 다수의 요청을 보낼 때 새로운 TCP 커넥션을 맺을 필요가 없습니다. 따라서, naver.com과의 HTTP 커넥션을 맺은 후, daum.net으로 이동하여 다시 naver.com으로 이동할 경우 이미 맺어진 커넥션을 재사용할 수 있습니다.
하지만 이것은 동일한 서버에 대한 요청이며, 서러 다른 서버에 대한 요청을 보낼 경우 매번 새로운 TCP 커넥션을 맺어야 합니다.
HTTP 1.1에서는 문제를 해결할 수 없습니다.
하지만, HTTP 2.0에서는 커넥션의 재사용을 더욱 확장시켜 여러 도메인에 대한 요청에 대해서도 하나의 커넥션으로 처리할 수 있게 되었습니다.
HTTP/2.0은 2015년에 공식 승인되어서, 이전에 개발되었던 브라우저나 서버에서는 지원하지 않을 수 있습니다. 그래서 현재까지도 많은 웹 사이트가 HTTP 1.1을 사용하고 있습니다. 하지만 점차적으로 HTTP/2.0을 적용하고 있는 곳이 늘어나고 있으며, 대부분의 최신 브라우저는 HTTP/2.0을 지원한다고 합니다.
하지만 근본적으로 TCP/IP 기반으로 한 HTTP 통신은 문제점이 존재합니다.
예를 들어, HTTP/2.0에서는 여러 개의 스트림을 하나의 TCP 커넥션으로 처리하기 때문에, 하나의 스트림에서 문제가 발생하면 해당 커넥션 전체가 중단될 가능성이 있습니다.
이러한 문제점을 해결하기 위해서 등장한 것이 HTTP/3.0입니다.
❗ HTTP/3.0은 인터넷 상에서 데이터를 주고 받는 프로토콜 중 하나인 HTTP의 최신 버전 중 하나입니다. 이전 버전인 HTTP/1.1과 HTTP/2.0에서 사용되던 TCP/IP 기반의 프로토콜을 대체하기 위해 개발되었습니다.
HTTP/3.0은 UDP 기반의 프로토콜인 QUIC(Quick UDP Internet Connection)을 기반으로 하고 있으며, UDP를 사용함으로써 더욱 빠른 전송 속도와 낮은 지연 시간, 더욱 강화된 보안 기능 등의 장점을 가지고 있습니다.
또한, HTTP/3.0에서는 기존의 HTTP/1.1과 HTTP/2.0에서 사용되던 TCP/IP 기반의 3-way handshake 방식 대신에 QUIC의 1-way handshake 방식을 사용하여 더욱 빠른 연결 시간을 제공합니다. 이를 통해, 이전 버전들보다 더욱 빠르고 안정적인 데이터 전송이 가능해졌습니다.
HTTP/3.0은 아직까지 많은 웹사이트에서 지원되지 않지만, 점차적으로 지원되는 사이트가 늘어나고 있습니다. 또한, HTTP/3.0은 기존 버전들과 호환성이 없으므로, HTTP/3.0을 지원하지 않는 클라이언트와 서버와는 통신이 불가능합니다.
크롬의 경우 QUIC 프로토콜을 사용하여 HTTP/3.0을 지원합니다. 하지만, QUIC을 지원하지 않는 웹사이트와의 통신을 위해서는 여전히 TCP를 사용하는 HTTP/1.1이나 HTTP/2.0 프로토콜을 사용해야 합니다.
즉, 만약 사용자가 QUIC을 지원하지 않는 웹사이트에 접속한다며나, 브라우저는 해당 웹사이트의 서버와 TCP 기반의 HTTP/1.1 또는 HTTP/2.0 연결을 맺게 됩니다. 따라서 사용자가 웹사이트에 접속하는 방식에 따라서 QUIC이 사요오디는 경우와 그렇지 않은 경우가 있을 수 있습니다.
이러한 이유로 현재 대부분의 웹사이트 개발자들은 HTTP/3.0을 지원하기 위해 많은 노력을 하고 있습니다. 하지만 아직까지 HTTP/3.0을 지원하지 않는 브라우저가 많이 있어서, 대부분의 웹사이트는 HTTP/2.0과 HTTP/1.1을 모두 지원하고 있습니다. 하지만 HTTP/3.0이 보다 빠른 전송 속도와 보안성을 제공하기 때문에, 앞으로 점차 HTTP/3.0을 지원하는 웹사이트가 더욱 많아질 것으로 예상이 된다고 지피티가 얘기하네요 ^^
QUIC 프로토콜에 대해선 추후에 다뤄볼 예정이니 이 부분은 여기까지 정리하도록 하겠습니다.