Web

HTTP ?

자바니또 2021. 9. 4. 00:32

개요

이번 포스팅의 목적은 HTTP의 중요 개념을 정리하기 위함이다. 굉장히 많이 사용하지만 그에 비해 뚜렷하게 실체가 보이지 않는 개념을 뚜렷하게 보기 위해 정리를 해보고자 한다. 

목차

  • 웹 브라우저 요청 흐름
  • HTTP : Hyphertext Transfer Protocol
  • HTTP 특징

웹 브라우저 요청 흐름

이전 포스팅에서 우리가 메시지를 서버에 보내는 과정을 다음과 같이 설명했다.

  1. 메시지를 생성한다. - 애플리케이션 계층
  2. SOCKET라이브러리를 사용하여 OS 계층으로 전달한다. - 애플리케이션 계층
  3. TCP 또는 UDP 정보를 생성하여 메시지 데이터에 포함시킨다. - 전송 계층
  4. IP 패킷을 생성하여 3번에서 만든 데이터를 포함시킨다. - 전송계층
  5. LAN 카드를 이용하여 서버와 통신 - 네트워크 인터페이스 계층

여기서 말하는 메시지가 바로 HTTP메시지다. 우리가 마우스를 통해 쉽게 접속하는 사이트는 대부분 HTTP, 요즘은 거기에 security기능이 추가된 HTTPS를 사용한다. 

HTTP : Hyphertext Transfer Protocol

HTTPHyphertext Transfer Protocol 의 준말이다. Hyphertext란 HTML(Hyphertext Markup Language)를 의미하고 해석하자면 HTML을 전송하기 위한 프로토콜이다.

등장했을 당시엔 이름과 같은 기능을 했지만, 요즘은 성능이 많이 좋아져서 대부분의 자원이 전송가능하다. 예를들면, JSON, XML, 사진, 음성, 영상, 파일 등 대부분이 HTML로 전송가능하며 그만 큼 많이 사용된다.

 사이트에 접속할 때 보내지는 요청 메시지들(좌: naver, 우: google)

위의 사진은 naver에 접속했을 때 클라이언트가 서버에게 요청하는 자원들이다. H2와 H3는 각각 HTTP/2 HTTP/3이다. 이미 많은 곳에서 쓰이고 있다. 이 프로토콜들은 HTTP1.1의 고수준의 문법(메서드, 상태필드, 헤더, URI)는 그대로 사용하여 기존의 서비스들에도 적용할 수 있게 설계되었다.

HTTP1.1은 css파일 등 페이지를 렌더링 할 때, 클라이언트가 서버에게 추가적인 요청(Pull request)을 통해 자원을 가져온다. 추가적인 트래픽이 발생할 수 밖에 없다.

효율적인 웹사이트는 이러한 자원들을 어떻게 축소하여 최소한의 메시지로 전달하느냐에 달려있다. 기존의 1.1 에서는 요청 메시지 헤더에 Transfer-Encoding: chunked 를 표기하여 서버에게 큰 용량의 자원을 적당히 나누어 보내달라하여 해결하는 방법이 있었다. HTTP/2는 이것을 서버가 알아서 보내주게함으로써 해결했다. 클라이언트는 하나씩 요청하여 자원을 받고 렌더링할 필요 없이 서버가 알아서 클라이언트가 렌더링 할 때 필요한 데이터를 보내준다. 

HTTP/3는 UDP특성을 사용한 프로토콜이다. TCP를 기반으로 작동하는 1.1과 2는 3-way-handshake라는 과정을 거치기 때문에 UDP보다 느리다는 단점이 있었다. HTTP/3에서는 UDP의 특성을 활용하여 보다 빠른 성능을 지원한다.

더 자세한 설명은 다음을 참고하길 바란다.

HTTP 특징

서버와 클라이언트 구조

HTTP는 서버와 클라이언트 사이에서 원하는 결과를 얻기위해 사용된다. 쉽게 말해 클라이언트는 서버에게 "이렇게 이렇게 해줘" 라는 의미를 담아서 보내고, 서버는 클라이언트에게 해당 요청이 잘 처리되었는지, 원하는 데이터가 있었다면 그 데이터까지 함께 보내준다. 즉, 서버와 클라이언트가 서로 소통하기 위한 메시지기능을 한다. 따라서 서버와 클라이언트 구조, 또는 Request Response 구조라고 한다. 

Stateless(무 상태성)

여기서 State(상태)는 이전의 HTTP 메시지들의 상태를 말한다. 즉, 내가 버튼을 한번 누름으로써 발생하는 요청들은 모두 제 각각의 역할을 하기위해 발송되고, 서로의 상태를 저장하지 않기 때문에 독립적으로 처리될 수 있다.

만약 상태를 가진다면 ? (Statful)

온라인 쇼핑을 예로들어 가정해보자. 다음과 같은 순서로 이루어진다.

  1. AB를 장바구니에 담는다. 
  2. 장바구니에서 A, B를 선택하여 구매하기 버튼을 누른다. 

1번과 2번은 서버에게 2번의 요청을 보낸다. 이때 1번과 2번은 A, B라는 아이템 정보가 겹친다. 이때 HTTP가 상태를 가지도록 하여 즉, 1번 HTTP 메시지에 A, B를 저장하도록 하고, 2번은 "구매해라"라는 명령만 저장하여 아이템은 1번 요청을 참조하도록 했다. 다음과 같은 상황이 발생한다.

  • 1번 요청을 받은 서버는 2번의 요청까지 자신이 받아야 한다. 2번 요청을 다른 서버가 받는 다면 어떤 아이템을 구매하는지 알 수 없다. 즉, 기능을 수행하기 위해 관련된 모든 요청을 탐색해야 한다. 
  • 즉, 서버를 여러대 두지 못하고 해당 서버의 장애 발생 시 굉장히 리스크가 커진다.

온라인 서비스가 발달하는 요즘시대에 서버를 여러대 두는 것은 흔하다. 그것이 여러명의 사용자를 효율적으로 처리하기 위한 제일 쉬운 방법이기 때문이다. 이것은 HTTP의 Stateless 특징으로 인해 가능해진다. Stateless를 위해 우리는 하나의 요청으로 하나의 기능을 온전히 수행할 수 있도록 필요한 데이터를 한번에 보내야 한다. 보내는 데이터의 양이 많아진다는 단점이 있지만, 얻는 장점이 더욱 크다. 

비연결성

여기서 연결이란 서버와 클라이언트가 통신하기 위해 TCP의 3-way-handshake를 거친 상태를 의미한다. 초기의 HTTP는 한번의 요청과 응답이 한번의 연결로 이루어졌다. 그래서 페이지를 그리고 필요한 이미지를 로드하기위해 요청을 할때는 다시 3-way-handshake를 거쳐야했다. 하지만 현재는 하나의 페이지를 모두 렌더링할 때까지는 연결이 유지되고, 그 다음에 끊어진다. 

정리

  • HTTP는 서버와 클라이언트가 기능을 수행하기 위해 사용되는 메시지 프로토콜이다.
  • HTTP는 Stateless이다. 때문에 단순한 구조를 갖고있고 확장이 용이하다.
  • HTTP의 Stateless 특성으로 여러대의 서버로 병렬 처리가 가능하다.