1. HTTP (HyperText Transfer Protocol)
HTTP 메시지를 통해 다양한 종류의 데이터를 전송할 수 있습니다. HTML, 텍스트, 이미지, 음성, 영상, 파일, JSON, XML 등 모든 형태의 데이터를 전송할 수 있습니다. 서버 간에 데이터를 주고받을 때에도 대부분 HTTP를 사용합니다.
HTTP는 HTTP/0.9부터 시작하여 HTTP/1.0, HTTP/1.1, HTTP/2, HTTP/3까지 이어집니다. HTTP/0.9 버전에는 GET 메서드만 지원하고 HTTP 헤더X가 없었습니다. 1997년에 등장한 HTTP/1.1은 가장 널리 사용되는 버전으로, 지금 HTTP의 대부분의 기능이 포함되어 있습니다. 이후에 등장한 HTTP/2와 HTTP/3는 성능 개선을 위해 개발되었고, 특히 HTTP/3는 UDP를 사용하여 TCP보다 빠른 전송 속도를 제공합니다.
HTTP/1.1과 HTTP/2버전은 TCP 프로토콜 기반으로 작동합니다. 하지만 TCP 프로토콜은 3-way handshake 등의 작업이 필요해 성능이 좋지 않은 부분이 있었습니다. 그래서 이후 등장한 HTTP/3는 더 빠른 전송을 위해 TCP 대신 UDP를 사용합니다. 현재는 주로 HTTP/1.1이 사용되지만, HTTP/2와 HTTP/3의 사용이 점차 증가하고 있습니다.
2. HTTP의 특징
(1) 클라이언트 서버 구조
HTTP 프로토콜을 통해 클라이언트와 서버 간의 통신은 요청(Request)과 응답(Response)의 형태로 이루어집니다.
클라이언트가 HTTP 메서드를 통해 서버에 요청을 보내면, 클라이언트는 서버에 대한 응답이 올 때까지 대기하게 됩니다. 서버는 요청에 대한 결과를 만들어 클라이언트에게 응답해주고, 다시 클라이언트가 응답을 받아 동작하게 되는 구조입니다. 이러한 구조에서 클라이언트와 서버는 분리되어, 각각 독립적으로 작동할 수 있습니다.
이전에는 클라이언트와 서버가 분리되어 있지 않았고, 일반적으로 웹 애플리케이션의 로직이 서버 측에서 처리되었습니다. 하지만 이런 클라이언트 서버 아키텍처가 도입되면서 데이터와 비즈니스 로직을 서버 측으로 밀어넣고, 클라이언트는 주로 사용자 인터페이스(UI)에 집중할 수 있게 되었습니다.
이런 클라이언트 서버 아키텍처를 통해 클라이언트와 서버가 독립적으로 성장할 수 있게 되었습니다.
(2) 무상태(Stateless) 프로토콜
여기서의 상태(State)란, 시스템이나 애플리케이션의 특정 시점에서의 상황이나 정보를 의미합니다. 이러한 상태를 유지하는 것과 관련된 프로토콜을 Stateful(상태 유지) 프로토콜이라고 합니다. 반면에 상태를 유지하지 않고 각 요청을 독립적으로 처리하는 프로토콜을 Stateless(무상태) 프로토콜이라고 합니다. HTTP는 Stateless(무상태) 프로토콜을 지향하는 특징이 있습니다.
예를 들어, 가게에서 물건을 사는 과정을 생각해보겠습니다.
상태 유지 방식(Stateful)에서는 고객이 물건을 구매하는 동안 점원이 물건의 개수와 가격을 계속해서기억하고 있어야 합니다. 그런데 이 방식은 중간에 다른 계산원이 들어오게 되면 그 계산원은 현재 상태를 알 수 없습니다. 그렇기 때문에 중간에 다른 점원으로 바뀌면 안되고, 만약 바뀌면 상태 정보를 미리 다른 점원에게 알려주어야합니다.
반면에 무상태(Stateless) 방식에서는 고객이 매번 구매할 때마다 개별적으로 계산을 하게 됩니다. 고객이 새로운 계산원에게 계속해서 새로운 데이터를 넘겨주게 됩니다. 그래서 해당 계산원은 새로운 주문만을 처리하면 되기 때문에 이전 주문과 관련된 정보를 신경쓰지 않아도 됩니다. 그래서 무상태 방식에서는 갑자기 고객이 증가해도 점원을 대거 투입할 수 있습니다.
즉 무상태 방식에서는 갑자기 클라이언트 요청이 증가해도 서버를 대거 투입할 수 있습니다. 무상태는 응답 서버를 쉽게 바꿀 수 있어 무한한 서버를 증설할 수 있습니다.
그림으로 비교하면 아래와 같습니다.
만약 Stateful 에서 중간에 서버가 장애나면, 클라이언트 A는 처음부터 다시 요청을 수행해야합니다.
Stateless는 상태를 보관하지 않기 때문에, 중간에 서버가 장애가 나면 중계 서버가 다른 서버로 보낼 수 있습니다. 그럼 서버 2에서 정상적인 응답을 보내줄 수 있습니다.
그래서 위 그림과 같이 수평 확장에 유리합니다.
하지만 실무에서는 모든 것을 무상태로 설계할 수 있는 경우도 있고 없는 경우도 있습니다.
예를 들어, 로그인이 필요 없는 단순한 서비스 소개 화면의 경우, 클라이언트가 서버에게 요청을 보낼 때마다 필요한 정보를 함께 전송하면 되므로 상태를 유지할 필요가 없습니다. 이는 무상태(Stateless)로 설계된 서비스입니다.
그러나 로그인과 같이 사용자의 상태를 서버가 유지해야 하는 경우도 있습니다. 로그인한 사용자의 경우 로그인 했다는 상태를 서버에 유지해야 사용자에게 맞춤화된 서비스를 제공하거나 보안을 유지할 수 있습니다. 이러한 경우에는 보통 브라우저 쿠키나 서버 세션을 사용하여 상태를 유지합니다.
이러한 상태 유지 기술은 최소한으로 사용하는 것이 좋습니다. 상태 유지가 필요한 경우에만 사용하고, 무상태 프로토콜을 유지하는 것이 성능과 확장성을 유지하는 데에 좋습니다.
(3) 비연결성
만약 클라이언트와 서버가 연결을 계속 유지하게 되면, 요청이 끝난 클라이언트와도 연결이 유지되기 때문에 서버 자원이 소모되는 문제가 발생합니다.
연결을 유지않는 모델에서는 요청 후 응답이 완료되면 서버의 연결을 끊어 버립니다. 그래서 서버는 연결을 유지하지 않고 최소한의 자원을 사용할 수 있습니다.
HTTP는 기본적으로 연결을 유지하지 않는 모델입니다.
일반적으로 초 단위 혹은 이하의 빠른 속도로 응답이 이루어지는데, 대부분의 경우 1시간 동안 수천 명의 사용자가 서비스를 사용하더라도 실제 서버에서 동시에 처리되는 요청은 수십 개 이하로 매우 적습니다. 예를 들어, 사용자가 웹 브라우저에서 계속해서 검색 버튼을 누르는 경우는 드뭅니다. 그래서 계속해서 서버를 연결하는 것은 서버 자원의 낭비입니다. 그런 상황에서 HTTP는 비연결성으로 인해 서버 자원을 매우 효율적으로 사용할 수 있습니다.
물론 비연결성의 한계도 있습니다.
우선 TCP/IP 연결을 새로 맺어야 하는 것입니다. TCP/IP 연결을 맺는 과정에는 3-way handshake라는 시간이 추가됩니다. 이로 인해 초기 연결 설정에 시간이 소요되는 단점이 있습니다. 이를 극복하기 위해 HTTP/1.1에서는 Keep-Alive라는 지속 연결 기능을 도입하여 한 번의 연결로 여러 요청과 응답을 주고받을 수 있도록 했습니다.
또, 다양한 자원을 동시 다운로드할 때에도 단점이 있습니다. 웹 페이지를 요청할 때 HTML 외에도 자바스크립트, CSS, 이미지 등 다양한 자원이 함께 다운로드되어야 합니다. 이러한 다중 자원을 동시에 처리하기 위해 지속적인 연결(Persistent Connections)을 사용합니다.
HTTP/1.1에서는 한 번의 TCP 연결로 여러 자원을 요청하고 응답받을 수 있도록 지속 연결 기능이 제공됩니다.
현재는 HTTP/2와 HTTP/3에서 더 많은 최적화 기능이 도입되어 비 연결성의 한계를 극복하고 있습니다. HTTP/2에서는 다중화와 헤더 압축 등의 기능을 제공하여 성능을 향상시켰고, HTTP/3에서는 TCP 대신 UDP를 사용하여 연결 속도와 전송 속도을 줄였습니다.
3. HTTP 메시지
HTTP 메시지의 구조는 아래와 같습니다.
시작라인과 헤더(header), 공백 라인(CRLF), message body로 구성됩니다,
HTTP 요청 메시지와 HTTP 응답 메시지는 구조가 조금 다릅니다. 요청 메시지는 시작 라인에 요청 메서드와 대상 URL이 포함되고, 응답 메시지는 시작 라인에 상태 코드와 설명문구가 포함됩니다
각각의 구역에 대해 조금 더 자세히 살펴보겠습니다.
(1) 시작 라인
HTTP 메시지의 시작 라인은 Request-line과 Status-line 이 있는데 요청 메시지와 응답 메시지에 대해 각각 다르게 구성됩니다.
요청 메시지
요청 메시지의 시작 라인은 요청 라인(request-line)으로 구성됩니다. 요청 라인은 아래와 같이 표현됩니다.
request-line = method SP(공백) request-target SP HTTP-version CRLF(엔터)
HTTP 메서드, 요청 대상, HTTP 버전으로 이루어져 있습니다.
- HTTP 메서드는 서버가 수행해야 할 동작을 지정합니다. GET과 POST 등이 있습니다.
- 요청 대상은 절대경로와 쿼리로 이루어져 있습니다. 절대경로는 "/"로 시작하고, 쿼리는 요청에 추가되는 매개변수입니다.
- HTTP 버전은 요청하는 클라이언트가 사용하는 HTTP 버전을 나타냅니다.
예를 들어, Google에서 "hello"를 검색하는 GET 요청은 아래와 같습니다.
GET /search?q=hello&hl=ko HTTP/1.1
Host: www.google.com
응답 메시지
응답 메시지의 시작 라인은 상태 라인(status-line)으로 구성됩니다.
status-line = HTTP-version SP status-code SP reason-phrase CRLF
HTTP 버전, HTTP 상태 코드, 그리고 이유 문구로 이루어집니다.
- HTTP 버전은 응답하는 서버가 사용하는 HTTP 버전을 나타냅니다.
- HTTP 상태 코드는 요청의 성공 여부나 실패를 나타내는 코드입니다. 예를 들어, 200은 성공, 400은 클라이언트 요청 오류, 500은 서버 내부 오류를 의미합니다.
- 이유 문구는 간결한 상태 코드에 대한 사람이 이해할 수 있는 설명 문구입니다.
요청이 성공적으로 처리된 경우의 응답은 아래와 같습니다
HTTP/1.1 200 OK
(2) HTTP 헤더
HTTP 헤더는 HTTP 전송에 필요한 모든 부가 정보를 포함하고 있습니다. 형식은 아래와 같습니다.
header-field = field-name ":" OWS field-value OWS (OWS:띄어쓰기 허용)
헤더는 메시지 바디의 내용, 크기, 압축 여부, 인증 정보, 클라이언트(브라우저)와 서버 애플리케이션 정보, 캐시 관리 등과 같은 다양한 정보를 제공합니다. 표준 헤더는 매우 많고, 필요에 따라 임의의 헤더를 추가할 수도 있습니다.
(3) HTTP 메시지 바디
HTTP 메시지 바디는 실제로 전송되는 데이터를 포함하고 있습니다. HTML 문서, 이미지, 영상, JSON 등과 같은 다양한 형식의 데이터를 전송할 수 있습니다.
참고자료
[인프런 김영한 - 모든 개발자를 위한 HTTP 웹 기본 지식]
https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard
'Backend > HTTP' 카테고리의 다른 글
[HTTP] HTTP 상태코드 (모든 개발자를 위한 HTTP 웹 기본 지식 - 섹션 6) (0) | 2023.04.25 |
---|---|
[HTTP] HTTP 메서드 활용 (모든 개발자를 위한 HTTP 웹 기본 지식 - 섹션 5) (0) | 2023.04.25 |
[HTTP] HTTP 메서드 (모든 개발자를 위한 HTTP 웹 기본 지식 - 섹션 4) (0) | 2023.04.21 |
[HTTP] URI와 웹 브라우저 요청 흐름 (모든 개발자를 위한 HTTP 웹 기본 지식 - 섹션 2) (0) | 2023.04.18 |
[HTTP] 인터넷 네트워크 (모든 개발자를 위한 HTTP 웹 기본 지식 - 섹션 1) (0) | 2023.04.17 |