on
HTTP 기본
김영한님의 모든 개발자를 위한 HTTP 웹 기본 지식을 공부하고 정리하는 포스트입니다.
HTTP 기본
모든 것이 HTTP
HTTP는 HyperText Transfer Protocol로 HTML을 전송하는 프로토콜로 시작되었다. 지금은 HTML, 텍스트 뿐만 아니라 이미지, 음성, 영상, 파일, JSON, XML 등등 거의 모든 형태의 데이터를 전송할 수 있다. 심지어 서버 간에 데이터를 주고 받을 때도 대부분 HTTP를 사용한다.
HTTP 역사
- HTTP/0.9 : 1991년. GET 메서드만 지원, HTTP 헤더 X.
- HTTP/1.0 : 1996년. 메서드, 헤더 추가.
- HTTP/1.1 : 1997년. 가장 많이 사용. 우리에게 가장 중요한 버전!
- RFC2068 (1997) -> RFC2616 (1999) -> RFC7230 ~ 7235 (2014)
- HTTP/2 : 2015년. 성능 개선.
- HTTP/3 : 진행중. TCP 대신 UDP 사용, 성능 개선.
HTTP/1.1에 대해서 공부하는 것이 가장 중요하다.
기반 프로토콜
HTTP/1.1, HTTP2의 경우 TCP 프로토콜 위에서 동작을 한다. HTTP/3는 UDP 기반으로 개발이 되어있는데, 왜냐하면 TCP는 3 way라던지, 많은 데이터로 인해 느린 속도 등의 문제로 성능을 최적화 시켜 사용하기 위해 UDP 위에서 개발되고 있다.
현재는 HTTP/1.1이 주로 사용되며 HTTP/2와 HTTP/3은 성능을 개선한 것으로 조금씩 증가하고 있다.
구글에서 검색을 한 후 개발자 도구에서 protocol을 살펴보면 h2 혹은 h3를 볼 수 있다. 이 것들이 바로 HTTP/2와 HTTP/3이다. 다른 사이트에서도 확인해보면 어떤 HTTP를 사용하고 있는지 볼 수 있다.
HTTP 특징
HTTP에는 중요한 특징들이 있는데, 먼저 HTTP는 클라이언트 서버 구조로 동작하게 되어있다. 그리고 무상태 프로토콜, Stateless라고하는 것을 지향하고 비연결성이라는 특징을 가지고 있다.
HTTP 메세지를 통해서 주고 받고 단순하고 확장이 가능하다.
클라이언트 서버 구조
HTTP의 첫 번째 특징인 클라이언트와 서버 구조를 살펴보자.
HTTP는 클라이언트가 HTTP 메시지를 통해서 서버에 요청을 보낸다. 그리고 클라이언트는 서버에서 응답이 올 때까지 무작정 대기한다. 그러다 서버가 요청에 대한 결과를 만들어서 응답을 하면 그 응답 결과를 열어서 동작하게 된다.
이렇게 클라이언트와 서버로 분리된 것이 중요하다. 비즈니스 로직과 데이터를 서버에 다 밀어넣고 클라이언트는 오직 UI와 사용성에만 집중한다. 이런 구조의 장점은 각각 독립적으로 진화할 수 있다.
Stateful, Stateless
HTTP의 중요한 특징 중 하나인 Stateless에 대해 알아보자. HTTP는 무상태 프로토콜을 지향하는데 서버가 클라이언트의 상태를 보존하지 않는다는 말이다. 이렇게 말해서는 이해하기 어려우니 예제를 보자.
stateful은 상태를 유지한다는 것이고, stateless는 상태를 유지하지 않는다는 것이다.
먼저, stateful은 다음과 같은 상황이다. 물건을 사러가서 점원에게 가격을 물어보고, 몇 개 살지 정한 다음, 결제 수단을 제시해서 결제를 완료하는 일련의 과정 속을 한 명의 점원과 계속 진행했다. 이 점원은 모든 요구사항을 다 기억하고 있다.
만일 물건을 구매하는 과정에 상대해주는 점원이 계속 바뀐다고 생각해보자. A라는 점원에게 물건의 가격을 듣고, B라는 점원에게 가서 몇 개 살지를 말하면 B라는 점원은 어떤 물건을 사려는 것인지 알지 못한다. 마찬가지로 C라는 점원에게 가서 카드로 결제한다고 말하면 C 점원은 물건도 모르고, 개수도 모르는 상태가 되어버린다.
이렇게 stateful한 상태는 서버가 클라이언트의 상태를 유지하고 있는 것이다. 점원이 고객이 어떤 물건을 살 것이고, 몇 개를 원하며, 어떤 결제방식을 사용할지와 같은 상태를 기억하고 있는 것이다.
이제 stateless는 어떻게 되는지 살펴보자. 위와 똑같은 상황인데, 대화를 할 때 매번 요구사항을 전달하는 것이다. 이렇게 하면 점원이 계속 바뀌는 상태에서도 요구사항이 전달되기 때문에 오류가 발생하지 않는다.
stateless는 서버가 클라이언트의 상태를 보관하지 않는다. 클라이언트가 매번 요구사항을 말하기 때문에 보관하지 않아도 되는 것이다.
즉 stateful에서는 점원이 바뀌면 오류가 발생하지만, stateless한 상태에서는 매번 필요한 데이터를 넘기기 때문에 점원이 바뀌어도 아무런 문제가 없는 것이다.
정리
- 상태 유지 : 중간에 점원이 변경되면 안된다. (점원이 바뀔 때 상태 정보를 다른 점원에게 미리 알려주어야 한다.)
- 무상태 : 중간에 점원이 변경되어도 된다.
- 갑자기 고객이 증가하여도 점원을 대거 투입할 수 있다. 즉, 클라이언트의 요청이 증가해도 서버를 대거 투입할 수 있다.
무상태는 응답 서버를 쉽게 바꿀 수 있어서 무한한 서버 증설이 가능하다.
한계
물론 모든 것을 무상태로 설계할 수 없는 경우도 존재한다. 예를 들어, 이벤트 소개 페이지는 로그인이 필요없기 때문에 무상태로 설계가 쉽지만 로그인이 필요할 경우에는 그러기 어렵다. 로그인한 사용자가 로그인 했다는 상태를 서버에 유지해야 하기 때문이다. 이러한 어쩔 수 없는 한계를 해소하기 위해 상태 유지를 최소한으로 사용하게 된다.
비연결성
TCP/IP 연결의 경우 기본적으로 연결을 유지한다. 이렇게 연결을 유지하는 모델의 경우 한 번 연결이 되었다면 지속적으로 연결을 유지하기 때문에 서버의 자원이 계속 소모된다. 이러한 모델의 단점은 다른 클라이언트들이 놀고 있어도(요청이 없어도) 서버가 계속 연결을 유지하고 있어야 한다.
반면에 연결을 유지하지 않는 모델의 경우 요청을 보내고 응답을 받고나면 연결을 끊어버린다. 그리고 새로운 요청이 오면 또 응답을 보내고 연결을 끊는다. 이런 식으로 연결을 유지하지 않기 때문에 서버의 소모자원을 최소한으로 할 수 있다.
HTTP는 기본적으로 연결을 유지하지 않는 모델이다. 일반적으로 초 단위 이하의 빠른 속도로 응답을 주고받기 때문에 1시간 동안 수 천명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청은 수 십개 이하로 매우 작다. 그렇기 때문에 서버 자원을 매우 효율적으로 사용할 수 있다.
한계와 극복
이러한 비연결성에도 단점이 있는데, 매번 TCP/IP 연결을 새로 맺어야 한다. 즉, 3 way handshake의 시간이 추가되는 것이다. 또한, 웹 브라우저로 사이트를 요청하면 HTML만 있는게 아니라 많은 자원들이 함께 다운로드된다.
이런 자원을 받을 때마다 연결을 했다가 끊었다가 하는게 너무 비효율적이다. 그래서 HTTP는 Persistent Connections, 지속 연결이라는 것을 기본적으로 사용한다. HTTP/2와 HTTP/3에서는 더욱 최적화가 되었다.
HTTP 메세지
HTTP는 요청 메세지와 응답 메세지의 구조가 조금 다르게 생겼다. HTTP 메세지의 전체적인 구조는 아래와 같다.
여기서 공백라인은 무조건 존재해야 한다.
이제 요청과 응답 메세지를 확인해보자.
시작 라인
시작 라인은 크게 request-line과 status-line으로 되어 있다. 요청 메세지는 request-line이라고 한다.
request-line은 method SP(공백) request-target SP HTTP-version CRLF(엔터)의 형태를 가지고 있다.
HTTP Method는 GET, POST, PUT, DELETE…등등이 있는데, 서버가 수행해야 할 동작을 지정하는 것이다.
request-target(요청 대상)은 절대 경로, absolute-path로 시작해서 쿼리가 들어간다. absolute-path[?query]
마지막에 HTTP version이 들어간다.
응답은 status-line으로 HTTP-version SP status-code SP reason-phrase CRLF의 형태를 가진다.
status-code, 상태 코드는 굉장히 중요한데 요청의 성공과 실패를 나타낸다. ex) 200, 400, 500 등등
HTTP 헤더
헤더 필드는 field-name “:” OWS(띄어쓰기 허용) field-value OWS의 형태를 가진다. field-name은 대소문자 구분이 없다.
이 헤더의 용도는 HTTP 전송에 필요한 모든 부가정보를 가지고 있다. ex) 메세지 바디의 내용, 크기, 압축, 인증, 요청 클라이언트 정보, 서버 애플리케이션 정보, 캐시 관리 정보 등등…
HTTP 메세지 바디
실제 전송할 데이터가 들어있다. byte로 표현할 수 있는 모든 데이터가 들어갈 수 있다.
Comments
CS 의 다른 글
-
HTTP 헤더 - 캐시와 조건부 요청 03 Jan 2022
-
HTTP 헤더 - 일반 헤더 26 Dec 2021
-
HTTP 상태코드 20 Dec 2021
-
HTTP 메서드 활용 17 Dec 2021
-
HTTP 메서드 12 Dec 2021
-
HTTP 기본 09 Dec 2021
-
URI와 웹 브라우저 요청 흐름 08 Dec 2021
-
인터넷 네트워크 06 Dec 2021
-
Single LinkedList 01 Oct 2021
-
ArrayList 24 Sep 2021
-
List Interface(리스트 인터페이스) 23 Sep 2021
-
자바 컬렉션 프레임워크 20 Sep 2021
-
면접 기초 질문 리스트 31 Aug 2021
-
인프라 기초 총정리 14 Aug 2021
-
하드웨어와 네트워크 기초 지식 03 Aug 2021
-
오버레이 네트워크(Overlay Network) 02 Aug 2021
-
이건 꼭 알고 가자! 면접 출제 빈도가 높은 질문들 19 May 2021
-
1분 자기소개 19 May 2021
-
백엔드 개발자 면접 / 학습내용 15 Feb 2021
-
너비 우선 탐색(breadth-first search, BFS) 22 Oct 2020
-
깊이 우선 탐색(depth-first search, DFS) 10 Oct 2020
-
크리티컬 섹션(Critical Section) 10 Sep 2020
-
삽입 정렬(Insertion Sort) 04 Sep 2020
-
선택 정렬(Selection Sort) 04 Sep 2020
-
거품 정렬(Bubble Sort) 04 Sep 2020
-
LRU 알고리즘 31 Aug 2020
-
Stack, Queue 29 Aug 2020
-
awk 명령어 사용법 24 Aug 2020
-
grep 명령어 사용법 23 Aug 2020
-
DNS의 이해 14 Aug 2020
-
대칭키와 공개키 10 Aug 2020
-
HTTP & HTTPS 10 Aug 2020