Server/HTTP

[HTTP] HTTP 기본

개발자킹콩 2022. 8. 10. 21:23

목차

  • 모든 것이 HTTP - 어디까지 할 수 있는가
  • Client Server 구조
  • Stateful, Stateless
  • Connectionless (비연결성)
  • HTTP Message

 


 

 

HTTP (HyperText Transfer Protocol)

HyperText(문서 간의 링크를 통해 연결할 수 있는 HTML)를 전송하는 규약으로 시작되었다.

현재는 모든 형태의 데이터를 HTTP를 통해서 전송한다.

(서버간의 통신도 TCP를 사용하지 않고 HTTP를 사용하며, 간혹 게임 서버 같은 경우에는 TCP 계층으로 통신하기도 한다.)

 

 

 


 

 

기능은 HTTP/1.1 에 다 들어있고 가장 많이 사용해서 가장 중요한 버전이다.

HTTP/2 와 HTTP/3 는 성능 개선만 추가되어 한 것이기에 많이 사용하지는 않는다.

RFC2616이 가장 보편화대고 대중적인 버전이다.

 

 

HTTP/3는 UDP 를 이용해 packet을 만든다.

전송 속도와 전달 데이터의 크기에 부담이 있는 TCP를 최적화 하기위해 UDP를 사용한다.

애플리케이션 레벨에서 성능 최적화를 통해서 나온 것이 HTTP/3 이다.

HTTP/2 와 HTTP/3 은 성능 개선이기 때문에, HTTP/1.1 의 스팩을 이해하는 것이 중요하다.

 

 


 

 


 

개념이 중요하다. 클라이언트와 서버를 개념적으로 분리하는 것이 중요하다.

데이터와 비지니스 로직은 서버에서 관리하고 집중한다.

클라이언트는 UI와 사용성을 관리하고 집중한다.

이것이 모듈화와 추상화이며, 하나에 집중이 가능하고 전문성은 올라가며 고도화가 진행된다.

 

예를 들어, 사용자가 겁나 늘어서 트래픽이 증가를 하게 되면 클라이언트에서는 손댈 것이 거의 없다.

서버에서 Architecture를 어떻게 할지, 서버의 기술을 어떻게 대용량으로 고도화 할지만 생각하면 된다.

 

 


 

서버의 가장 큰 특징은 무상태 프로토콜을 지향한다.

 

 


 

  • 상태 유지에서는 다른 점원으로 바뀌면 서비스 장애가 발생한다.
  • Stateless에서는 요청때 마다 필요한 정보를 다 넘겨서 점원이 바껴도 문제가 발생하지 않는다.
  • 이러한 점이 Stateless가 Client & Server Architecture로 선택된 이유이다.
  • 이로 인해, 엄청난 확장성을 갖고 무한 증식이 가능하다.

 

 


 

 

 

클라이언트의 요청을 서버1에서만 받아야 하고, 서버1에 문제가 생기거나 다른 서버에 요청이 들어가면 상태를 저장하고 있지 않기 때문에 처음부터 요청을 다시 해야한다.

 

Stateless의 경우 서버는 상태를 저장하지 않는다. 클라이언트가 요청시, 필요한 데이터를 담아서 보낸다.

이렇게 되면 서버1이 문제가 생기거나 다른 서버에 요청이 들어가도 정상적인 응답을 받을 수 있다.

 

 


 

Scale out - 수평 확장

 

이렇게 Stateless를 사용하면 Scale out(옆 서버를 쫙~ 늘리는 것)을 하는데 굉장히 유리하다.

 

Stateless도 한계가 존재한다. 모든 것을 무상태로 만들 수는 없다.

이벤트 소개 페이지의 경우 상태를 유지할 필요가 없다. 이런 경우 무상태로 설계하는 것이 매우 간단하다.

 

하지만, 상태를 유지해야 하는 로그인의 경우이다.

로그인한 사용자가 로그인 했다는 상태를 서버에서 유지하고 있어야 한다.

이를 위해 브라우저의 쿠키와 서버의 세션을 조합해서 상태를 유지하는 기능을 사용한다.

상태 유지의 경우 최소한으로만 사용하고, 어쩔 수 없이 사용해야 하는 경우에만 사용한다.

 

그리고, Stateless의 경우 데이터를 너무 많이 보낸다는 단점이 존재한다. 

 

 


 

 

Connectionless (비연결성)

 

 

연결을 유지하는 모델의 경우 요청을 보내지 않는 상태에서도 연결을 유지해야 하고 이는 서버 자원의 소모를 의미한다.

 

 

요청과 응답이 이루어지면, 그 뒤 연결을 유지하지 않고 끊어버린다.

이로 인해, 서버에서 연결을 유지함으로 생기는 리소스 자원을 아낄 수 있다.

그림은 3개의 클라이언트라서 굳이 이렇게 해야되나 생각하지만, 클라이언트가 100만개 였으면 이것을 리소스 소모를 굉장히 많이 줄인 것으로 확인할 수 있다.

 

 


 

 

지속 연결을 통해 어떻게 문제해결을 했는지 살펴보자

 

 

지속 연결은 요청을 보낸 뒤 응답을 받고 연결을 유지한다. 몇십초를 유지하거나 등 내부 메커니즘은 모두 다르지만 웬만한 HTML 파일을 받을 때까지는 지속연결로 유지한다. 그 뒤 연결이 종료된다. HTTP 2와 3에서는 더욱 최적화해서 빠르고, 심지어 HTTP3에서는 UDP Protocol를 사용해서 연결 속도도 확 줄여냈다.

 

 

 


 

이렇게 좋은 방법으로 서버를 설계하는데 수강신청 할 때는 왜 잘 안되는 걸까??

 

같은 시간 요청을 하면 비연결성은 의미가 없다. 모두 00시 00분 00초에 요청이 들어와서 비연결성의 장점을 살릴 수가 없다. 핵심은 어떻게든 머리를 쥐어짜서 Stateless하게 설계하는 것이 중요하다. 그렇게 하면 이런 대용량 트래픽이 발생해도 서버를 확 늘려서 대응할 수 있는 방법이 많아진다. (여담으로 요청 버튼을 누르기 전 상태를 저장할 필요없는 소개페이지를 두어 조금의 대응을 하는 것도 작은 아이디어이다.)

 

 

 


 

 

 

HTTP 메세지

 

 

 

HTTP 메세지 구조에서 공백 라인은 반드시 필요하다.

 


 

 

 

  • Request HTTP Message는 start-line에 request-line이 들어간다.
  • request-line에는 method, request-target(요청하는 대상: path), HTTP version이 들어간다.
  • Method: Get은 서버에 데이터를 달라고 요청하는 것, Post는 데이터를 줄테니 처리해달라는 의미...
  • request-target: / 를 이용해 절대경로를 사용한다.

 


 

 

  • 응답 메세지의 경우 start-line은 status-line이다.
  • status-line에는 HTTP 버전, 상태코드, reason-phrase(사람이 이해 가능한 짧은 글) 

 


 

  • header에는 key:value 가 들어가며, OWS는 공백을 넣어도 되고 넣지 않아도 됨을 의미한다.
  • 그래서 key와 ' : ' 사이를 띄우는 것은 허용되지 않는다.

 

  • 사실 상세내용은 Header에 다 들어있다.
  • body의 데이터가 어떤 것인지(Content-Type)
  • 어떤 문자형태를 띄는지(charset)
  • 데이터 크기(Content-length) - 메세지 body 의 크기
  • 압축이 되었는가? 인증정보, 요청 브라우저 정보, 애플리케이션 정보, Cache, ...

물론 임의의 헤더를 추가할 수 있으며, 추가하면 약속한 클라이언트와 서버만 알 수 있다.

 

 

 

압축해서 보내면 압축된 내용이 들어간다