춸처
HTTP (HyperText Transfer Protocol)
모든 것이 HTTP!
HTTP는 HTTP 메시지에 모든 것을 담아 전송합니다.
- HTML, Text
- Image, 음성, 영상, 파일
- JSON, XML (API)
거의 모든 형태의 데이터 전송이 가능합니다. 서버 간에 데이터를 주고 받을 때도 대부분 HTTP를 사용합니다.
(실무에서 서버간의 통신을 할 때 TCP 프로토콜을 직접 이용해서 데이터를 전송하는 경우는 거의 없습니다.)
지금은 HTTP 시대
HTTP 역사
- HTTP 0.9 : 1991년, GET 메서드만 지원, HTTP 헤더 X
- HTTP 1.0 : 1996년, 메서드와 헤더 추가
- HTTP 1.1 : 1997년, 가장 많이 사용, 우리에게 가장 중요한 버전
- 버전: RFC2068 (1997) -> RFC261(1999) -> RFC7230~7235 (2014)
- HTTP 2 : 2015년, 성능 개선
- HTTP 3 : 진행중, TCP 대신에 UDP 사용, 성능 개선
기반 프로토콜
- TCP : HTTP 1.1 HTTP 2
- UDP : HTTP 3
HTTP 1.1 버전과 HTTP 2 버전은 TCP 프로토콜 기반에서 돌아가며, HTTP 3 버전은 UDP 프로토콜 기반에서 돌아갑니다.
현재 HTTP 1.1 을 주로 사용합니다. HTTP 2와 HTTP 3도 점점 증가하고 있습니다. (Naver 와 Google 에서 F12 를 눌러 Network 에 Protocol 창을 열어 보면 h2와 h3을 쓰고 있는 것을 볼 수 있습니다.)
참고 : TCP 대신 UDP로 대체되는 이유?
1. 3-way-handshake 가 번거롭다.
2. 안에 데이터가 너무 많다.
3. 매커니즘 자체가 속도가 빠른 매커니즘이 아니다.
UDP 프로토콜 위에 애플리케이션 레벨에서 성능을 최적화하도록 새로 설계해서 나온 것이 HTTP 3 입니다.
HTTP 1.1 만 배워놓으면 2 와 3 은 성능을 개선한 것이기 때문에 크게 다를 것이 없습니다.
HTTP 특징
- 클라이언트- 서버 구조
- 무상태 프로토콜 (Stateless), 비연결성 (Connectionless)
- HTTP 메시지
- 단순함, 확장 가능
클라이언트 서버 구조
- Request, Response 구조
- 클라이언트는 서버에게 요청을 보낸 후 응답을 대기
- 서버가 요청에 대한 결과를 만들어 응답
- 예전엔 클라이언트와 서버가 분리되어 있지 않았다.
- 클라이언트와 서버를 분리해 서버에서는 비지니스 로직과 데이터를 처리하도록 하고, 클라이언트는 UI와 사용성에 집중하도록 분리
- 이렇게 분리하면 양쪽이 독립적으로 진화할 수 있다는 장점이 있다.
무상태 프로토콜 (Stateless)
- 서버가 클라이언트의 상태를 보존하지 않는 프로토콜입니다.
- 장점: 서버 확장성이 높음 (스케일 아웃)
- 단점: 클라이언트가 추가 데이터를 전송해야 한다.
Stateful ? Stateless?
① Stateful (상태 유지)
다음 예시를 통해 살펴봅시다.
고객: 이 노트북 얼마인가요?
점원: 100만원입니다.
고객: 2개 구매하겠습니다.
점원: 200만원입니다. 신용카드, 현금 중에 어떤 걸로 구매하시겠어요?
고객: 신용카드로 구매하겠습니다.
점원: 200만원 결제 완료되었습니다.
만약, 중간에 점원이 바뀐다면?
고객: 이 노트북 얼마인가요?
점원 A: 100만원입니다.
고객: 2개 구매하겠습니다.
점원 B: ? 무엇을 구매하시겠어요?
고객: 신용카드로 구매하겠습니다.
점원 C: ? 무슨 제품을 몇 개 신용카드로 구매하시겠어요?
Stateful 상태에선 클라이언트(고객)이 보내는 데이터를 서버(점원)이 저장해둡니다.
따라서 이처럼 서버(점원)이 교체된다면 클라이언트(고객)가 하는 말을 알아듣지 못합니다.
정리
고객: 이 노트북 얼마인가요?
점원 A: 100만원입니다. (노트북 상태 유지)
고객: 2개 구입하겠습니다.
점원 A: 200만원입니다. 신용카드, 현금 중에 어떤 거로 구매하시겠어요? (노트북, 2개 상태 유지)
고객: 신용카드로 구매하겠습니다.
점원 A: 200만원 결제 완료되었습니다. (노트북, 2개, 신용카드 상태 유지)
② Stateless (무상태)
고객: 이 노트북 얼마인가요?
점원: 100만원입니다.
고객: 노트북 2개 구매하겠습니다.
점원: 노트북 2개는 200만원입니다. 신용카드, 현금 중에 어떤 걸로 구매하시겠어요?
고객: 노트북 2개를 신용카드로 구매하겠습니다.
점원: 200만원 결제 완료되었습니다.
무상태는 서버가 상태를 유지하지 않기 때문에 클라이언트가 서버에게 필요한 데이터를 매번 모두 전달합니다.
점원이 중간에 바뀐다면 어떻게 될까요?
고객: 이 노트북 얼마인가요?
점원A : 100만원입니다.
고객: 노트북 2개 구매하겠습니다.
점원 B: 노트북 2개는 200만원입니다. 신용카드, 현금 중에 어떤 걸로 구매하시겠어요?
고객: 노트북 2개를 신용카드로 구매하겠습니다.
점원 C: 200만원 결제 완료되었습니다.
Stateful 과 달리 서버에서 데이터를 저장하지 않고 클라이언트가 필요한 데이터를 모두 전송하기 때문에 서버가 교체되어도 문제가 되지 않습니다.
정리
- 상태 유지(Stateful): 점원이 중간에 바뀌면 안됩니다.
- 무상태 (Stateless): 중간에 다른 점원으로 바뀌어도 됩니다.
- 갑자기 고객이 증가해도 점원을 대거 투입할 수 있습니다.
- 갑자기 클라이언트 요청이 증가해도 서버를 대거 투입할 수 있습니다.
- 무상태는 응답 서버를 쉽게 바꿀 수 있는 장점이 있습니다. 즉, 무한한 서버 증설이 가능합니다.
- 하지만 무상태는 많은 데이터를 전송해야 한다는 단점이 있습니다.
상태 유지 - Stateful
: 항상 같은 서버가 유지되어야 한다. (ex) 클라이언트 A는 서버1하고만 통신해야 한다.)
if. 중간에 서버가 장애가 난다면?
지금까지 통신하던 서버 1에 상태를 저장해뒀기 때문에, 클라이언트 A는 다른 서버와 처음부터 다시 통신해야 합니다.
무상태 - Stateless
: 아무 서버나 호출해도 된다.
if. 중간에 서버가 장애가 난다면?
중개 서버가 서버 1이 에러가 나면 서버 2로 요청을 보내면서 해결이 가능합니다.
따라서, 무상태는 스케일 아웃 (수평 확장)에 유리합니다.
Stateless 실무 한계
- 모든 것을 무상태로 설계할 수 있는 경우도 있고, 없는 경우도 존재합니다.
- 무상태로 설계하기 쉬운 경우
- ex) 로그인이 필요없는 단순한 서비스 소개 화면 → 장애가 별로 발생하지 않습니다.
- 무상태로 설계하기 어려운 경우 (상태를 유지해야 하는 경우)
- ex) 로그인
- 로그인한 사용자의 경우 로그인을 했다는 상태를 서버에 유지해야 합니다.
- 일반적으로 브라우저 쿠키와 서버 세션을 함께 사용하여 상태를 유지합니다.
- 서버의 세션이 날아가거나 세션 서버가 죽어버리면 전체적인 로그인이 풀려버립니다.
- 상태 유지는 최소한만으로만 사용해야 합니다.
- Stateless 의 단점은 데이터를 너무 많이 전송합니다.
비 연결성 (connectionless)
TCP/IP의 경우 기본적으로 연결을 유지합니다.
연결을 유지하는 모델
클라이언트 1과는 계속 연결이 되어 있는 상태입니다.
연결을 유지하느라 서버 자원을 계속 소모합니다.
연결을 유지하지 않는 모델
연결을 유지하지 않기 때문에 최소한의 자원만 소모합니다.
클라이언트 1에서 또 요청이 들어온다면 재연결 후 응답 합니다.
비연결성
- HTTP는 기본이 연결을 유지하지 않는 모델입니다.
- 1시간동안 수천명이 서비스를 이용해도 실제 서버에서 동시에 처리하는 요청은 수십개 이하로 매우 적습니다. 예를 들어, 웹 브라우저에서 한 사람이 연속해서 계속 검색 버튼을 누르지는 않습니다. 즉, 한 개의 클라이언트가 연속해서 요청을 보내는 일은 거의 없습니다.
- 따라서 연결을 유지하면서 자원을 소모하는 것보다, 연결을 끊고 다시 요청이 들어왔을 때 다시 연결 후 응답을 하는 것이 서버 자원을 효율적으로 사용할 수 있습니다.
비연결성 단점과 극복
- 비 연결성 방식의 단점은 TCP/IP 연결을 매번 새로 맺어야 한다는 것입니다. 이는 3 way handshake 시간이 추가됩니다. - 연결을 설정하고 해제하는 오버헤드가 발생
- 웹 브라우저로 사이트를 요청하면, HTML 뿐만 아니라 자바스크립트, css, 추가 이미지 등 많은 자원들이 함께 다운로드됩니다. 따라서 매번 자원을 받을 때마다 TCP/IP 연결을 매번 새로 맺는 건 비효율적입니다.
- 이는 HTTP 지속 연결(Persistent Connections) 로 문제를 해결합니다.
- 클라이언트가 서버에 여러 HTTP 요청을 보낼 때 매번 새로운 연결을 설정하는 대신, 일정 시간동안 한 번의 연결을 유지하고 여러 요청과 응답을 주고 받는 것을 의미합니다.
- 이는 웹 페이지 로딩 속도를 개선하고 네트워크 리소스를 효율적으로 사용할 수 있습니다.
- HTTP 1.0 에서는 기본적으로 비지속인 연결이었으나, HTTP 1.1부터 "Connections: keep-alive" 헤더를 명시함으로써 Persistent Connections 를 사용할 수 있습니다.
- HTTP 2, HTTP 3에서 더 많은 최적화가 가능해졌습니다.
HTTP 초기 - 연결, 종료 낭비
매번 연결과 종료를 반복합니다.
HTTP 지속 연결 (Persistent Connections)
- 요청이 끝날 때까지 내부적으로 다를 수 있지만 몇 십초동안 연결을 유지합니다.
- HTTP 2와 HTTP 3 에선 더 빠르게 해결합니다.
- HTTP 3은 UDP 프로토콜을 사용해 연결 속도를 더욱 줄였습니다.
스테이스리스를 기억하자!
서버 개발자들은 정말 같은 시간에 딱 맞춰 발생하는 대용량 트래픽 업무를 어려워합니다.
- 예) 선착순 이벤트, 명절 KTX 예약, 학과 수업 등록
- 예) 저녁 6:00 선착순 1000명 치킨 할인 이벤트 → 수만명이 동시 요청
이럴 땐 최대한 Stateless하게 설계하는 것이 중요합니다. 서버를 늘려서 대응할 수 있기 때문입니다.
HTTP 메시지
: HTTP 메시지에 모든 것을 전송합니다.
HTTP 메시지의 구조는 다음과 같이 정해져 있습니다.
- 시작 라인
- 헤더
- 공백 (반드시 들어가야 합니다.)
- 메시지 바디
요청 메시지의 시작 라인 (start-line)
- state-line 은 reqeust-line 과 status-line 으로 나뉩니다.
- 요청 메시지의 경우 request-line 이라고 합니다.
- request-line 은 다음과 같은 구조로 이루어집니다.
method SP request-target SP HTTP-version CRLF
- SP는 공백, CRLF는 엔터를 의미합니다.
- method: HTTP 메서드 (ex) GET (조회))
- request-target: 요청 대상 (ex) /search?q=hello&hl=ko)
- HTTP-version : HTTP 버전 정보 (ex) HTTP / 1.1)
HTTP 메서드
- 종류에는 GET, POST, PUT, DELETE 등이 있습니다.
- 서버가 수행해야 할 동작을 지정합니다.
- GET: 리소스 조회
- POST: 요청 내역 처리
요청 대상 (request-target)
- 절대 경로를 써줍니다. absolute-path[?query]
- 절대경로란 "/"로 시작하는 경로를 의미합니다.
- 참고로 * 나 http://...?x=y 와 같은 다른 유형의 경로 지정 방법도 있습니다.
HTTP 버전
응답 메시지의 시작 라인 (start-line)
- start-line은 request-line 과 status-line 으로 나뉘는데 응답 메시지의 경우 status-line 이라고 합니다.
- status-line 은 다음과 같은 구조로 이루어집니다.
HTTP-version SP Status-code SP reason-phrase CRLF
- SP는 공백, CRLF 은 엔터를 의미합니다.
- HTTP-version
- Status-code : HTTP 상태 코드를 의미합니다. 요청의 성공 또는 실패를 나타냅니다.
- 200: 성공
- 400: 클라이언트 요청 오류
- 500: 서버 내부 오류
- reason-phrase : 이유 문구로 사람이 이해할 수 있는 짧은 상태 코드 설명 글을 의미합니다. (ex) OK)
HTTP 헤더
- header-field 는 다음과 같은 구조로 이루어집니다.
field-name: OWS field-value OWS
- OWS는 띄어쓰기를 허용한다는 의미입니다.
- 여기서 주의할 것은 field-name 과 : 사이 공백이 들어가면 안됩니다. (ex) Host : www.google.com X)
- field-name 은 대소문자 구분이 없으나 field-value는 대소문자를 구분합니다.
HTTP 헤더의 용도
- HTTP 전송에 필요한 모든 부가 정보가 들어갑니다.
- 예) 메시지 바디의 내용, 메시지 바디의 크기, 압축 여부, 인증, 요청 클라이언트(브라우저)의 정보, 서버 애플리케이션의 정보, 캐시 관리 정보 등
- 메시지 바디 빼고 필요한 메타 데이터가 모두 들어갑니다.
- 표준 헤더는 매우 많습니다. (강의 뒤편에서 정리할 예정입니다)
- 필요시 임의의 사용자 지정 헤더를 추가할 수 있습니다.
- 예) helloworld: hihi
HTTP 메시지 바디 용도
- 실제 전송할 데이터를 의미합니다.
- HTML 문서, 이미지, 영상, JSON 등 byte로 표현할 수 있는 모든 데이터 전송이 가능합니다.
HTTP는 단순함, 확장이 가능
- HTTP는 단순합니다. 스펙도 읽어볼만 합니다.
- HTTP 메시지도 매우 단순합니다.
- 크게 성공하는 표준 기술은 단순하지만 확장이 가능한 기술입니다.
HTTP 정리
- HTTP는 메시지에 모든 것을 담아 전송할 수 있습니다.
- HTTP의 역사, HTTP 1.1 을 기준으로 학습하길 바랍니다.
- 클라이언트 - 서버 구조 입니다.
- 무상태 프로토콜 (Stateless) 입니다.
- HTTP 메시지
- 단순함, 확장이 가능하다
- 지금은 HTTP 시대
'CS > 네트워크' 카테고리의 다른 글
[HTTP] HTTP Method (0) | 2023.04.17 |
---|---|
[네트워크] CORS에 대해 알아보자 (0) | 2023.04.13 |
[네트워크] 네트워크 기초 (0) | 2023.04.11 |
[HTTP] TCP / UDP 에 대해 알아보자 (0) | 2023.04.05 |
[HTTP] IP (인터넷 프로토콜) (0) | 2023.04.05 |