Home HTTP
Post
Cancel

HTTP

HTTP

HTTP

HyperText Transfer Protocol

웹에서 이루어지는 모든 데이터 교환의 기초로 HTML 문서와 같은 리소스를 가져올 수 있도록 해주는 클라이언트 - 서버 프로토콜이다.

HTTP의 특징

http는 크게 무상태성과 비연결성 두 가지 특징을 가지고 있다.

1. 무상태성

서버가 클라이언트를 식별할 수 있게 해주는 것을 상태라고 부른다.

위에서 말했듯이 http는 상태를 가지지 않는 무상태라고 이야기했는데 그럼 HTTP 요청을 받을 때 서버는 요청의 주체가 누구인지를 모른다는 것을 뜻한다. 이는 곧 요청을 신뢰할 수 없다는 말과 동일하며 매번 요청이 들어올 때 마다 인증 과정을 거쳐야한다.

  1. 사이트에 접속
  2. 로그인
  3. 마이 페이지
  4. 로그인

이대로 서비스하는 것은 말도 안되게 비효율적이며, 이를 해결하기 위해서 몇가지 방법이 존재한다

상태를 기억하는 방법

1. 쿠키

set-cookie를 이용해 브라우저 쿠키에 사용자 정보를 저장하고, HTTP 쿠키 헤더에 담아서 요청이 오갈 때 서버에서 쿠키를 조회해 클라이언트를 식별할 수 있게 하는 방법

2. 세션

브라우저에 저장되어있는 사용자 정보는 해커의 공격으로부터 취약하다.

그래서 이를 보완하기 위해 사용자 정보를 서버에다 저장하는 방법이 나왔는데 이것이 세션이다.

  1. 사용자가 로그인하면
  2. 데이터베이스에서 일치하는지 확인하고
  3. 세션 정보를 만들어둔 뒤 클라이언트에게 넘겨준다.
  4. 그럼 쿠키와는 다르게 사용자 정보 대신 세션 정보를 브라우저에 저장하고
  5. 쿠키 헤더에 세션 정보를 담아서 서버에 요청한다.
  6. 요청을 받은 서버는 3에서 만든 세션 정보와 일치하는지 확인한다.

이런 세션을 이용한 상태 저장 방법은 서버에 로그인한 유저의 상태를 전부 저장하기 때문에 동시 접속자가 많아질수록 서버에서 부담해야하는 리소스가 커진다는 단점이 있다

3. 토큰

로그인시에 정보가 일치하면 토큰화해서 클라이언트에 넘겨주는 방법

클라이언트는 받은 토큰을 저장해서 요청하는데 세션과는 다르게 서버에서는 요청시에 받은 토큰을 복호화해서 유효한지 확인만하면 된다.

그래서 서버에서는 따로 상태를 저장할 필요가 없어 부담이 덜하다.

비연결성

비연결성은 클라이언트와 서버가 연결되어있지 않는 상태를 말한다

HTTP는 TCP/IP를 기반으로 만들어진 프로토콜이고 TCP/IP는 3-way-handshake를 시작으로 하는 연결지향적 프로토콜이다. 그런데 어째서 TCP/IP를 기반으로하는 HTTP는 비연결성을 띠고 있는 것일까?

실제로 HTTP는 자원을 효율적으로 사용하기위해 데이터를 주고 받을 때 서버와 클라리언트가 연결되고 데이터 교환이 끝나면 연결을 끊는 비지속연결 통신으로 비연결성의 특징을을 띤다.

비지속연결 HTTP

보통 브라우저가 요청을 보내서 받아오게 되는 페이지는 HTML, CSS, JS, 이미지, 영상.. 등등 여러 파일을 받아와서 사용자에게 보여주어야한다.

그렇다는 말은 HTTP로 필요한 파일들을 받아올 때 하나의 파일을 받고 연결을 끊고 다시 받아오고 연결을 끊고.. 를 반복해야하는데 TCP/IP 를 기반으로 만들어진 프로토콜인만큼 연결 마다 3-way handshake가 발생하게 되고 이 연결 수가 늘어날수록 지연시간이 늘어나 비효율적인 통신이 되어버린다.

지속연결 HTTP

위의 단점을 개선하고자해서 나온 방법이 지속 연결 HTTP인데 자원을 요청했을 때 묶여있는 모든 자원을 받아올 때까지 연결을 유지하고 있는 것을 말한다.

HTTP 1.0 버전에서는 헤더에 Keep-Alive 옵션을 주면 지속 연결이 가능하다.

HTTP 1.1

누가 봐도 Keep-Alive 옵션을 주는 것이 통신 효율이 좋아보인다. 이를 똑똑한 사람들이 모를리 없을테니 조금 더 발전된 버전인 1.1버전에서는 해당 옵션을 명시하지 않을 경우 기본 값으로 모든 연결이 지속 연결로 처리된다.

Pipelining

이미지

또 통신 시간을 단축하기 위해 pipelining이라는 기술을 도입했는데

이전의 통신 방법은 클라이언트가 보낸 요청에 의해 응답이 오기 전까지 다른 요청을 보내지 못했지만 pipelining을 도입함으로써 클라이언트는 일단 요청을 마구 보내놓고 순서대로 서버에게서 응답을 받아 대기 시간을 단축시키는 방법이다.

Head Of Line Blocking

이 pipelining도 문제점이 있었는데 클라이언트의 첫 요청이 시간이 오래 걸리거나, 문제가 생겼을 경우 두 번째 요청이 아무리 빠르게 응답할 수 있는 요청이어도 응답할 수 없는 현상. 이 때문에 전체적인 응답 시간이 지연된다.

다중 TCP 연결

TCP는 하나의 연결에 하나의 응답만 전달받을 수 있도록 보장되기 때문에 여러개의 응답을 병렬적으로 받기 위해서 서버와 여러개의 TCP 통신을 연결한다.

이러한 다중 연결은 HOL를 불러오고 TCP 연결의 비효율적인 사용을 초래한다.

HTTP 2.0

1.1에서 성능을 항샹 버전

바이너리 프레이밍 계층

기존 1.1 버전에서는 Plain Text를 사용하고 개행을 통해 헤더와 본문을 구분했다면 2.0에서는 바이너리 포맷으로 인코딩된 메시지와 프레임으로 구성된다.

image

이를 이용함으로써 파싱, 전송속도가 빨라지게 됐다.

멀티 플렉싱

2.0에서는 프레임으로 구성된 메시지를 하나의 커넥션에서 여러개의 스트림으로 다중 전송이 가능해졌다.

덕분에 비효율적인 TCP연결 부분이 해결되었으며 각 프레임마다 식별자를 가지고 있어서 꼭 순서대로 응답이 돌아오지 않아도 되게 되었고 따라서 HOL문제가 해결됐다.

TCP 자체의 문제

하지만 http 2.0의 스트림을 이용한 통신도 TCP 프로토콜을 사용하기 때문에 TCP 자체에 있는 HOL의 문제는 해결할 수가 없다.

스트림 우선순위 지정

순서대로 오지 않는 응답 프레임에 따라서 클라이언트가 우선순위 지정 트리를 구성하고 통신할 수 있다. 이 트리는 클라이언트가 선호하는 응답 수신 방식을 나타내며 서버에서 이 트리 정보를 사용해서 스트림 처리의 우선순위를 지정해 높은 순위에 따라 클라리언트에게 최적으로 전달하도록 대역폭을 할당한다.

서버 푸시

클라이언트가 요청하지 않은 정보에 대해서 서버가 알아서 데이터를 보내주는 것.

index.html에서 참조하고 있는 css나 js 파일들이 있다면 클라이언트가 index.html만 요청하고 나머지 파일들을 요청하지 않아도 어짜피 필요할 것이라 판단하고 서버측에서 css와 js파일을 자체적으로 보낸다.

헤더 압축

static dynamic table을 이용하여 중복되는 정보는 table의 인덱스만 남기고 중복되지 않은 정보는 Huffman 인코딩을 하여 헤더를 압축해서 요청할 때 마다 중복되는 헤더를 줄여서 헤더를 압축해 헤더의 크기를 최대 85%까지 줄였다.

QUIC

2.0의 문제를 탈피하기 위해서 UDP를 기반으로 통신하는 프로토콜

왜 UDP인가?

TCP는 신뢰성을 확보하기 위해 이미 너무 많은 기능들이 들어가있어서 그 자체를 손보기 힘들다고 판단해서 새하얀 백지같은 UDP에다가 개발자가 신뢰성을 불어넣으면서 지연 시간을 더 줄일 수 있다.

구글은 데이터 전송의 신뢰성을 어플리케이션 계층에 구현했고 따라서 3-way handshake를 사용할 필요가 없다.

향상된 멀티 플렉싱

image (1)

2.0은 하나의 TCP 연결 내부에서 스트림 통신을 하기 때문에 HOL를 근본적으로 해결할 수 없었지만 QUIC은 스트림 자체가 여러개이기 때문에 하나의 스트림에서 병목현상이 생기더라도 다른 스트림에 영향을 주지 않는다.

https://victorydntmd.tistory.com/286

https://jins-dev.tistory.com/entry/HTTP11-%EC%9D%98-HTTP-Pipelining-%EA%B3%BC-Persistent-Connection-%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC

https://developers.google.com/web/fundamentals/performance/http2?hl=ko

This post is licensed under CC BY 4.0 by the author.