HTTP/2 - 좀 더 자세히 알아보기

Heechan Kang·2024년 5월 24일
0

HTTP 톺아보기

목록 보기
3/5
post-thumbnail

다시 한 번, 뒤돌아보기

지난 주에 보셨던, HTTP/1.1과 HTTP/2의 속도 비교 데모입니다. 이 데모를 통해 두 가지 특징을 눈으로 확인 할 수 있습니다.

첫 번째로, HTTP2가 확연히 빠르다는 점을 알 수 있습니다. 뭐 데모의 목적상 당연하겠죠?
그리고 두 번째로는, HTTP/1.1은 랜덤한 순서로 리소스를 받아오는 반면, HTTP/2는 순차적으로 리소스를 받아온다는 점입니다. 두 번째 특징이야말로 좀 더 h2의 특징을 잘 보여준다고 할 수 있겠습니다.

다시 약간의 복습을 곁들여 들여다 보겠습니다.
HTTP/1.1은 keep-alive 헤더를 사용하긴 하지만 여전히 단일 요청/응답 방식을 사용합니다. 또한 브라우저는 동시에 오직 6개의 TCP 커넥션만을 사용할 수 있습니다. 따라서 1024개의 요청이 (거의) 동시에 전송되더라도 (각각의 네트워크 사정에 따라)먼저 도착한 요청이 먼저 처리되어야 합니다. 결과적으로 마치 스프레이를 뿌리듯 리소스가 랜덤하게 도착하게 됩니다.

반면에 HTTP/2의 경우에는 하나의 TCP 커넥션이면 충분합니다. 이 커넥션 안에서, 추상화된 스트림을 통해 여러 요청을 동시에 처리할 수 있게 되었습니다. 따라서 메모리가 허락하는 한 거의 무제한의 스트림을 사용할 수 있으며, 이들은 순차적으로 요청/처리됩니다. 따라서 HTTP/1.1에 비해 좀 더 선형적인 리소스 로딩을 확인 할 수 있습니다.

좀 더 가까이서 본 HTTP/2의 모습

오늘의 메인 주제로, 위 데모 페이지에서 발생한 h2 요청을 패킷 단위로 좀 더 자세히 들여다보겠습니다.

  • HTTP/1.1 요청의 패킷

  • HTTP/2 요청의 패킷

현재 h1, h2 서버는 각각 3001, 3002포트에서 서빙중입니다.
h1의 경우에는 메인 페이지를 서빙중인 3000번 포트의 요청이 함께 캡처되어있네요.

h1의 경우 Source Port가 거의 매 요청마다 바뀌는 것을 볼 수 있습니다. 즉 요청-응답 개념이 확실히 드러나는 것이죠.
여기서 제가 '거의'라고 표현한 이유는, 분명 keep-alive로 인해 재활용되는 커넥션(58155, 58156, 58157번 포트)이 분명하게 눈에 띄기 때문입니다.

반면 h2의 경우, 3002포트로 들어간 요청에 의해 58161번 포트로 새 TCP 커넥션이 생성되고, 이를 통해 h2 거의 모든 요청이 이루어지는 것을 볼 수 있습니다. 또한 h1에는 존재하지 않는 Stream Identifier라는 필드가 존재하는 것도 볼 수 있습니다.

이제 패킷 하나를 좀 더 자세히 열어보겠습니다. 가장 먼저 전송되는 HEADERS 타입의 프레임입니다.

전반적인 모습은 지난 글에서 보셨던 것과 크게 다르지 않습니다.
주요 특징으로는 아래와 같은 것들이 있습니다.

  • length 필드가 가장 먼저 표기된다.
  • Stream Identifier 필드가 존재한다.
  • 상태줄(HTTP/2 200 OK)이 헤더화 되어있다.

이외에는 전반적으로 h1의 형태와 크게 다르지 않습니다.
물론, 위 이미지의 경우는 Wireshark에서 h2를 디코딩한 결과이기 때문에, 실제로 전송되는 데이터는 바이너리로 인코딩되어 있습니다.
이를 프레임의 관점에서 자세히 살펴보면 아래와 같습니다.

실제 패킷과 비교해 보시면, 각각의 프레임이 어떤 구조로 이루어져 있는지를 확인할 수 있습니다.
이러한 규격화된 프레임 구조를 통해 h2는 더 빠르고 안정적인 데이터 전송을 가능하게 해줍니다.

다만 이 케이스에서는 이미지가 1,024등분되어 매우 작은 관계로, 약간 아쉽습니다.
따라서 좀 더 큰 데이터를 전송하는 경우 어떻게 될지 보기위해, 네이버 포털의 패킷을 한번 살펴보겠습니다.

위 이미지의 경우, 59503번 포트를 사용하는 TCP 커넥션을 통해 연결된 통신 중 15번 스트림의 패킷을 캡처한 것입니다.

WINDOW_UPDATE 프레임을 통해, 클라이언트가 서버에게 전송할 수 있는 데이터의 양을 늘리고자 하는 모습을 볼 수 있습니다.
(이미지 하단, 131,072 -> 12,582,912) 정말 빠르게 늘어나네요.

다음 패킷을 보니 데이터 전송량이 늘어난 모습을 볼 수 있습니다.

위와 같은 커넥션을 통해 여러 패킷이 전송되고 있으며, 이를 다시 조합해보면 결과적으로 아래와 같은 데이터가 전송되었음을 볼 수 있습니다.

잘은 모르겠지만 네이버 쇼핑과 관련된 페이지의 리소스인것 같네요. 네이버도 역시 nextjs를 쓰는군요.

이어지는 패킷에서는 다음 스트림의 데이터를 볼 수 있습니다. 이번에는 상대적으로 더 작아 보이네요.

계속해서 같은 TCP 커넥션을 사용하고있음을 알 수 있습니다(59503 -> 443).
이를 통해 h2의 특징 중 하나인 하나의 TCP 커넥션을 통해 여러 요청을 동시에 처리할 수 있음을 확인할 수 있습니다.

이번에는 제가 로그인 했는지 여부를 확인하는 것 같네요.

오늘은 이렇게, HTTP/2가 어떻게 움직이는지 아주 조금 더 가까이에서 보았습니다.
이러한 특징들을 통해 h2는 더 빠르고 안정적인 데이터 전송을 가능하게 해주었습니다.

원래는 HTTP/2를 거쳐 HTTP3까지 자세하게 알아보는 시간을 가지고싶었으나, 꽤 어렵고 고단했네요.
여기까지 이 부족한 글을 읽어주셨다면 다시한번 감사드리고, 다음에는 좀 더 갈무리해서 더 좋은 글을 써보도록 하겠습니다!

profile
안녕하세요!

0개의 댓글