HTTP 기본

CHOI·2022년 6월 3일
0

HTTP

목록 보기
3/3
post-thumbnail

모든 것이 HTTP

HTTP 는 HyperTest Transfer Protocol

HyperTest 문서를 전송하는 프로토콜로 시작했다.

그런데 지금은 모든 것을 HTTP 에 담아서 전송한다

  • HTML, TEXT
  • IMAGE, 음성, 영상, 파일
  • JSON, XML (API)
  • 거의 모든 형태의 데이터 전송 가능
  • 서버간의 데이터를 주고 받을 때도 대부분 HTTP 를 사용
  • 지금은 HTTP 시대

역사

대부분의 기능은 HTTP/1.1 에 개발되었고 그 이후로 개발된 HTTP/2 나 HTTP/3 는 성능 개선이 된 버전이다.

기반 프로토콜

  • TCP : HTTP/1.1, HTTP/2 는 TCP 위에서 동작한다.
  • UDP : HTTP/3 는 UDP 기반으로 개발되었다.
  • 현재 : HTTP/1.1 주로 사용
    • HTTP/2, HTTP/3 도 점점 증가

실제로 구글에서 개발자 모드로 하고 검색을 해보면 프로토콜에 h3(HTTP/3) 를 사용하는 것을 볼 수 있다.

특징

  • 클라이언트 서버 구조
  • 무상태 프로토콜(스테이리스), 비연결성
  • HTTP 메시지를 통해서 통신
  • 단순함, 확장 가능

클라이언트 서버 구조

  • Request Response 구조
  • 클라이언트는 서버에 요청을 보내고 응답을 대기
  • 서버가 요청에 대한 결과를 만들어서 응답

HTTP 는 클라이언트 서버 구조로 되어 있다. 클라이언트가 HTTP 메시지를 생성해서 서버에게 요청을 보내고 응답이 올때까지 기다린다. 서버가 요청에 대한 응답을 만들어서 응답이 오면 응답 결과를 열어서 클라이언트가 동작하게 된다.

매우 단순한 구조이다.

그런데 이렇게 클라이언트와 서버를 분리를 하는 것이 중요하다. 이전에는 클라이언트와 서버가 한 뭉탱이에 있었다. 이렇게 분리를 하여 비즈니즈 로직과 데이터 같은 것은 서버에 다 밀어 넣고 클라이언트는 UI 와 사용성에만 집중한다.

이렇게 분리를 하면 좋은 점은 클라이언트와 서버가 각각 독립적으로 진화할 수 있다. 클라이언트는 복잡한 데이터를 다룰 필요가 없고 그냥 단순하게 UI 를 어떻게 그릴 것인가 어떻게 하면 사용자가 더 편하게 사용할 수 있는가에만 집중하면 된다.

서버도 사업이 잘되어서 트래픽이 100배 증가 한다고 하였을 때 클라이언트 부분은 손댈 필요 없이 서버에서 어떻게 대용량 트래픽을 관리할지에만 집중하면 된다.

Stateful, Stateless

  • 서버가 클라이언트의 상태를 보존X
  • 장점 : 서버의 확장성 높음(스케일 아웃)
  • 단점 : 클라이언트가 추가 데이터 전송

Stateful, Stateless 차이

HTTP 의 중요한 특징 중 하나로 무상태 프로토콜을 지향한다는 것이다. 이것을 영어로 Stateless 라고 한다.

이게 무슨말인가 하면 다음 예제를 보자.

Stateful 은 서버가 클라이언트의 이전 상태를 보존한다는 것이다. 위 예시로 보면 문맥을 보존한다는 것이다.

Stateful 상황을 풀어서 살펴보자.

고객이 노트북이 얼마냐고 물어보면 점원은 100만원이라고 말하면서 노트북이라는 상태를 유지한다. 즉, 고객이 노트북을 사려고 한다는 것을 유지한다.

고객이 2개를 구매한다고 하면 점원은 200만원이라고 얘기할 수 있다. 왜냐하면 고객이 노트북을 구매하려고 한다는 상태를 알고있기 때문이다. 그리고 결재 수단을 물어보면서 점원은 고객이 노트북을 구매하고 2개 구매한다는 상태를 유지한다.

고객이 신용카드로 구매하겠다고 하면 점원은 고객이 노트북을 2개를 신용카드로 구매하겠다는 것을 알고 결재를 완료한다. 노트북, 2개, 신용카드 ****상태를 유지한다.

Stateless 상황을 보자.

이전과 차이를 볼 수 있을 것이다. 무상태에서는 고객이 필요한 정보를 다 넘겨준다. 그래서 중간에 점원이 바뀌어도 아무 문제 없다.

정리

  • 상태 유지 : 중간에 다른 점원으로 바뀌면 안된다.
    • 중간에 다른 점원으로 바뀔 때 상태 정보를 다른 점원에게 미리 알려줘야 한다.
  • 무상태 : 중간에 다른 점원으로 바뀌어도 된다.
    • 갑자기 고객이 증가해도 점원을 대거 투입할 수 있다.
    • 갑자기 클라이언트 요청이 증가해도 서버를 대거 투입할 수 있다.
    • 상태 유지면 상태를 관리하는 것이 어려워서 어려운데 무상태면 서버 증설해서 아무때나 들어와도 된다.
  • 무상태는 응답 서버를 쉽게 바꿀 수 있다. → 무한한 서버 증설 가능

그림을 통해서 살펴보자. 먼저 Stateful 이다.

클라이언트A 가 요청을 보내면 서버1 이 응답을 하면서 서버1은 클라이언트가 노트북을 2개 사고 싶다는 상태를 유지하고 있다. 이렇게 되면 서버를 늘리기 어렵다. 왜냐하면 클라이언트A 는 서버1 하고만 통신해야 하기 때문이다.

여기서 문제가 있다.

중간에 서버1이 장애가 오면 클라이언트A 는 다른 서버와 처음부터 다시 해야한다.

그런데 Stateless 는 애초에 요청할 때 부터 필요한 데이터를 다 담아서 서버에게 요청한다.

서버는 상태를 보관하지 않는다.

그러면 만약 서버1이 장애가 나면 다른 서버와 통신하면 된다. 중간에 다른 문맥이 필요 없다. 필요 데이터를 클라이언트가 다 담아서 보내주기 때문에 거기에 대한 응답만 해주면 된다.

서버를 쫘악 늘리는 것을 스케일 아웃이라고 하는데 이것을 수평 확장이라고 한다.

무상태는 스케일 아웃에 굉장히 유리하다.

그래서 큰 이벤트를 한다고 하면 백엔드에서는 장비를 수십대 늘릴 수 있다.

Stateless 한계

  • 모든것을 무상태로 설계할 수 있는 경우도 있고 없는 경우도 있다.
  • 무상태
    • 예 : 로그인이 필요 없는 단순한 서비스 소개 페이지
  • 상태 유지
    • 예 : 로그인
  • 로그인한 사용자의 경우 로그인 했다는 상태를 서버에 유지
  • 일반적으로 브라우저 쿠키와 서버 세션등으로 상태 유지
  • 상태 유지는 최소한만 사용
  • 무상태는 상태유지보다 데이터를 많이 보낸다는 점도 있다.

비 연결성(connectionless)

연결을 유지하는 모델

연결을 유지하는 모델에 대해서 먼저 살펴보자.

클라이언트1이 서버와 TCP/IP 로 연결을 한다음에 요청을 보내고 응답을 받는다.

그러고 클라이언트2가 서버에 접속해서 요청을 보내고 응답을 받는다.

이때 클라이언트1과 서버는 연결을 유지하고 있는다.

그러고는 클라이언트3도 서버와 연결을 한다. 이동안 클라이언트1과 클라이언트2는 서버와 연결을 유지하고 있다.

이러면 연결을 유지하는 서버의 자원이 계속 소모되고 있는 것이다.

그러다가 다시 클라이언트1의 요청이 오면 서버가 응답을 할 것이다.

이러한 방식의 단점은 클라이언트2와 클라이언트3이 놀고 있어도 서버가 연결을 계속 유지해야하는 단점이 있다.

연결을 유지하지 않는 모델

그러면 이번에는 연결을 유지하지 않는 모델에 대해서 살펴보자.

클라이언트1에서 서버와 연결을 하고 요청을 보내고 응답을 받았다.

그러면 볼일이 끝나서 즉시 클라이언트1과의 연결을 종료한다.

클라이언트2와 3도 똑같이 서버와 연결을 해서 요청과 응답을 받고 그 즉시 바로 연결을 종료한다.

이러한 방식의 장점은 자원을 요청을 주고 받을 때만 연결을 유지하고 그 다음에는 끊어버려서 서버가 유지하는 자원을 최소한으로 줄인다.

비연결성

  • HTTP는 기본이 연결을 유지하지 않는 모델
  • 일반적으로 초 단위의 이하의 빠른 속도로 응답
  • 1시간 동안 수천명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청은 수십개 이하로 매우 작음
    • 예 : 웹 브라우저에서 계속 연속해서 검색 버튼을 누르지는 않는다.
  • 서버 자원을 매우 효율적으로 사용할 수 있음

한계와 극복

  • TCP/IP 연결을 새로 맺어야 함 - 3 way handshake 시간 추가
    • 예를 들어서 웹 사이트에서 검색을 하다가 다음 페이지로 넘어가는 버튼을 누르면 서버와 다시 연결을 맺어야 한다. 이말은 즉, 다시 3 way handshake 로 클라이언트와 서버를 연결하는 시간이 걸린다.
    • 하나 자원을 받을 때 마다 연결하고 다시 끊고 다시 연결하고 하는 작업이 너무 비효율적이다. 그래서 HTTP 지속 연결로 문제 해결
  • 웹 브라우저로 사이트를 요청하면 HTML 뿐만 아니라 자바스크립트, css, 추가 이미지 등등 수 많은 자원이 함께 다운로드
  • 지금은 HTTP 지속 연결(Persistent Connections)로 문제 해결
  • HTTP/2, HTTP/3 에서 더 많은 최적화

HTTP 지속 연결

HTTP 초기 - 연결, 종료 낭비

웹 사이트 접속을 한다고 요청을 하면 연결을 하고 HTML 을 요청하여 응답 받고 종료한다. 그런데 이 웹 사이트에서는 자바스크립트도 필요해서 또 연결을 하고 요청하여 자바스크립트를 응답 받고 연결을 종료한다. 그런데 또 보니까 이 웹사이트는 이미지도 필요한 것이다. 그러면 또 연결해서 요청, 응답 받고 종료하고 너무 비효율 적이다.

HTTP 지속 연결 (Persistent Connections)

지속 연결의 경우는 웹 사이트에 연결해서 HTML 을 응답 받고 연결을 유지하여 더 필요한 자바스크립트와 이미지도 요청하여 응답 받고 종료한다.

내부적인 로직에 따라 다르지만 몇 ms 만큼 유지하는 등의 방식으로 웬만한 웹 사이트에 필요한 자원을 다 받을 때 까지 연결을 유지한다.

HTTP/2 와 HTTP/3 에서는 이러한 지속 연결을 더 최적화 하였다,

스테이스리스를 기억하자.

서버 개발자들이 어려워하는 업무

  • 정말 같은 시간에 딱 맞추어 발생하는 대용량 트래픽
  • 예) 선착순 이벤트, 명절 KTX 예약, 학과 수강 신청
  • 예) 저녁 6시 선착순 1000명 치킨 할인 이벤트 → 수만명 동시 요청

HTTP 메시지

다시 한번 더 모든 것이 HTTP 이다!

HTML, TEXT, 이미지, 영상, 음성, 파일 JSON, XML, 등등 거의 모든 형태의 데이터를 HTTP 메시지로 전소안다. 서버간의 데이터를 주고 받을 떄도 대부분 HTTP 를 사용한다. 바야흐로 지금은 HTTP 시대

구조

이전에 보았듯이 HTTP 요청 메시지와 HTTP 응답 메시지는 조금 달랐다. 먼저 HTTP 메시지 구조에 대해서 살펴보자.

  • start-line 시작 라인
  • header 헤더
  • empty line 공백 라인(CRLF)
  • message body

이런식으로 있다. 여기서 empty line 은 무조건 있어야 한다.

공식 스펙에서도 볼 수 있다. message body 는 올수도 안올수도 있다.

시작 라인

시작 라인은 request line 과 status line 으로 나눠져 있다.

요청 메시지 (request line)

  • start-line = request-line / status-line
  • request-line = method SP(공백) request-target SP HTTP-version CRLF(엔터)

요청 메시지 - HTTP 메서드

  • 종류 : GET, POST, PUT, DELETE
  • 서버가 수행해야 할 동작 지정
    • GET : 리소스 조회
    • POST : 요청 내역 차리

요청 메시지 - 요청 대상

  • absolute-path[?query] : 절대경로[?쿼리]
  • 절대경로 / 로 시작하는 경로
  • 참고 : * , https://....?x=y 와 같은 유형으로 경로를 지정하는 방법도 있음
  • 그냥 절대경로로 시작한다 라고만 알고 있어도 됨

요청 메시지 - HTTP 버전

  • HTTP 버전

응답 메시지

  • start-line = request-line / status-line

  • status-line = HTTP-version SP status-code SP reason-phrase CRLF

  • HTTP 버전

  • HTTP 상태 코드 : 요청 성공, 실패를 나타냄

    • 200 : 성공
    • 400 : 클라이언트 요청 오류
    • 500 : 서버 내부 오류
  • 이유 문구 : 사람이 이해할 수 있는 짧은 상태 코드 설명 문구

HTTP 헤더

  • header-field = field-name : OWS field-values OWS (OWS : 띄어쓰기가 있어도 되고 없어도 됨)
  • field-name : 대소문자 구분 없음
  • field-value 는 대소문자 구분함

용도

  • HTTP 전송에 필요한 모든 부가 정보
  • 예 : 메시지 바디의 내용, 메시지 바디의 크기, 압축, 인증, 요청 클라이언트(브라우저) 정보, 서버 어플리케이션 정보, 캐시 관리 정보..
  • 메시지 바디 빼고 필요한 모든 메타 정보가 있음
  • 표준 헤더가 너무 많음
  • 필요시 임의의 헤더 추가 가능
    • hellowolrd: hihi

HTTP 메시지 바디

용도

  • 실제 전송할 데이터
  • HTML 문서, 이미지, 영상, JSON 등등 byte로 표현할 수 있는 모든 데이터 전송 가능

단순함 확장 가능

  • HTTP는 매우 단순하다. 스펙도 볼만하다..
  • HTTP 메시지도 매우 단순
  • 크게 성공하는 표준 기술은 단순하고 확장 가능한 기술

정리

  • HTTP 메시지에 모든것을 전송할 수 있음
  • HTTP 역사 HTTP/1.1을 기준으로 학습
  • 클라이언트 서버 구조
  • 무상태 프로토콜(스테이리스)
  • HTTP 메시지
  • 단순함, 확장 가능
  • 지금은 HTTP 시대
profile
벨로그보단 티스토리를 사용합니다! https://flight-developer-stroy.tistory.com/

0개의 댓글