티스토리 뷰
인프런 김영한 님의 모든 개발자를 위한 HTTP 웹 기본 지식 강의를 듣고 내용을 정리한 글입니다.
1. 모든 것이 HTTP
HTTP(Hyper Text Transfer Protocol)
지금은 HTTP 시대. 모든 것이 HTTP를 통해 이루어진다.
HTML, TEXT, IMG, 음성, 영상, 파일, JSON, XML(API) 등 거의 모든 형태의 데이터를 전송할 수 있고
서버 간에 데이터를 주고 받을 때도 대부분 HTTP를 사용한다.(TCP를 직접 연결하는 경우는 매우 특별한 경우)
HTTP 역사
- 0.9/ 1991년/ GET 메소드만 지원. HTTP 헤더 없음
- 1.0/ 1996년/ 메소드, 헤더 추가
- 1.1/ 1997년/ 가장 많이 사용하고 가장 중요한 버전
- 2.0/ 2015년/ 성능 개선
- 3.0/ 진행중/ TCP 대신 UDP사용. 성능 개선
현재는 1.1을 가장 많이 사용하며 2와 3의 사용도 점점 늘고 있다.
1.1과 2는 TCP가 기반이고, 3은 UDP가 기반이다.
HTTP 특징
HTTP의 특징으로는 크게 네 가지로 나눠 볼 수 있다.
- 클라이언트-서버 구조
- 무상태 프로토콜(스테이스리스), 비연결성
- HTTP 메세지
- 단순함. 확장 가능
2. 클라이언트 서버 구조
클라이언트는 서버에 요청(requset)을 보내고 서버의 응답(response)을 대기한다.
서버는 클라이언트의 요청에 대한 결과를 만들어 응답한다.
즉 서로 요청과 응답을 주고 받는 구조다. (request <-> response)
이렇게 클라이언트와 서버가 분리되어있는 게 매우 중요한데, 이렇게 분리되어 있으면 서로 따로 발전, 변화할 수 있기 때문이다.
예를 들어 비즈니스 로직은 서버에만 작성하고 클라이언트는 오로지 UI에 관련된 코드만 작성하면
서버는 어떤 로직을 갖고 있든 클라이언트에게 응답만 보낼 수 있으면 되고,
반대로 클라이언트는 어떤 UI를 갖고 있든 서버에게 정확한 요청을 보내고 응답에 따라 화면만 그려줄 수 있으면 된다.
서버의 언어를 바꾸든, 인프라를 늘리든 클라이언트는 전혀 상관없다.
3. Stateful, Stateless
기본적으로 HTTP는 무상태(stateless) 프로토콜이다.
stateless 스테이트리스
서버가 클라이언트의 상태를 보존하지 않는 것을 말한다.
- 장점: 서버의 확장성이 높음(스케일아웃)
- 단점: 클라가 불필요한 데이터를 전송할 수 있음
예시
상태유지(stateful)
- 클라이언트: 이 노트북 얼마인가요?
- 서버1: 100만원입니다 (노트북 상태 유지)
- 클라이언트: 2개 구매할게요
- 서버1: 200만 원입니다. 신용카드, 현금 중에 뭐로 계산하시겠어요? (노트북, 2개 상태 유지)
- 클라이언트: 신용카드요
- 서버1: 200만 원 결제되었습니다. (노트북, 2개, 신용카드 상태 유지)
위와 같이 클라이언트가 이전에 말한 것을 서버에게 다시 말하지 않는 것(서버가 클라이언트의 상태를 저장)을 stateful, 상태 유지라고 한다.
이때 근데 중간에 서버가 바뀌면 문제가 발생한다.
- 클라이언트: 노트북 얼마죠?
- 서버1: 100만 원입니다.
- 클라이언트: 2개 구매할게요
- 서버2: ?? 무엇을 2개 사신다는 거예요?
- 클라이언트: 신용카드로 구매할게요
- 서버3: ?? 무엇을, 몇 개, 신용카드로 구매하신다는 거예요?
위와 같이 서버가 전혀 클라이언트의 요청을 알아듣지 못한다. 장애가 발생하는 것이다.
그럼 무상태, stateless의 예시를 보자
- 클라이언트: 노트북 얼마죠?
- 서버1: 100만 원입니다.
- 클라이언트: 노트북 2개 구매할게요
- 서버2: 노트북 2개는 200만 원입니다. 신용카드, 현금 중에 뭐로 결제하시겠어요?
- 클라이언트: 노트북 2개 신용카드로 구매할게요.
- 서버3: 200만 원 결제 완료되었습니다.
위처럼 stateless한 상황에서는
클라이언트가 요청할 때마다 자신이 필요한 모든 정보를 요청하기 때문에 서버가 아무리 중간에 바뀌어도 적절할 응답을 받을 수 있다.
정리하자면
- stateful 상태유지: 중간에 다른 서버로 바뀌면 안된다. 바뀌려면 상태 정보를 다른 서버에게 미리 알려줘야 한다.
- stateless 무상태: 중간에 다른 서버로 바뀌어도 된다. 갑자기 요청이 증가해도 서버를 대거 투입할 수 있다.
stateless는 응답 서버를 쉽게 바꿀 수 있기 때문에, 무한한 서버 증설 가능해진다. 클라와 소통하던 서버가 장애가 나도 다른 서버로 대체해도 아무런 문제가 없다.
stateful하다면 항상 같은 서버가 유지되어야 하며 어떤 클라이언트가 소통하던 서버가 장애가 난다면 클라이언트는 요청 과정을 처음부터 다시 해야 한다.
따라서 최대한 stateless하게 소프트웨어를 설계하는 것이 중요하다.
stateless 실무 한계
모든 것을 무상태로 설계할 수 없는 경우도 있다.
예를 들어 로그인 같은 경우에는 로그인이 되어 있는 상태를 유지해줘야만 한다.
일반적으로 로그인 같은 경우는 브라우저 쿠키와 서버 세션 등을 사용해서 상태 유지한다.
중요한 것은 기본적으로 stateless하게 설계하고, 필요할 때만 stateful하게 설계해야 한다.
웹어플리케이션을 설계할 때는 최대한 무상태로. 필요한 경우에만 상태 유지해야 한다.
4. 비연결성 connectionless
TCP/IP는 연결을 유지한다.
예를 들어 클라이언트가 요청을 보내면 서버가 응답하고
클라2가 요청하면 서버도 응답한다.
이때 서버는 클라 1, 2와 연결을 계속 유지하고 있다.
클라이언트가 요청을 하지 않아도 서버와 클라가 계속 연결을 유지하고 있어야 하기 때문에 불필요한 리소스가 낭비된다.
HTTP의 비연결성
HTTP는 기본적으로 연결을 유지하지 않는다.(connectionless)
요청이 있을 때만 연결 후 응답을 하고 연결을 끊어버린다.
서버 입장에서는 요청을 주고받을 때만 연결을 유지하기 때문에 최소한의 자원만을 사용할 수 있다.
일반적으로 초단위 이하의 빠른 속도로 응답이 완료되기 때문에
1시간 동안 수천명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청은 수십개 이하로 매우 작다.
예) 일반적인 사람은 웹 브라우저에서 계속 연속해서 검색 버튼을 누르지는 않는다.
따라서 비연결성을 통해 서버 자원을 매우 효율적으로 사용할 수 있다.
비연결성의 한계와 극복
TCP/IP연결을 매번 새로 맺어야 한다. 즉 3 way handshake를 매번 해야 해서 지연시간이 늘어난다.
웹 브라우저로 사이트를 요청하면 HTML뿐만 아니라 자바스크립트, css, 추가 이미지 등 수많은 자원이 함께 다운로드되는데,
이때마다 3 way handshake를 매번하면 당연히 연결시간만큼의 시간이 낭비된다.
하지만 요즘 HTTP는 지속연결(Persistent Connections)로 위 문제를 해결한다.
HTTP2 HTTP3에서 지속연결이 훨씬 더 최적화
지속 연결을 하지 않으면 요청이 있을 때마다 연결하고 끊어서 연결, 끊는 시간이 계속 추가되지만
지속 연결을 하면 일정시간 동안 연결을 유지해서 요청과 응답이 모두 끝날때까지 연결시켜준다.
번외
정말 같은 시간에 딱 맞춰 대용량 트래픽 발생하는 때가 있다.
예를 들면 선착순 이벤트, 명절 KTX예약, 학과 수업 등록 등의 일이다.
최대한 스테이트리스하게 설계해놓고 이벤트 시간에 맞춰 서버를 증설하여 해결하는 게 정석이다.
불가피하게 스테이트풀을 유지해야 한다 하더라도
이벤트 버튼을 누르기 전까지는 순수한 HTML 페이지 만들어 놓는 등 하여
클릭의 시간을 좀 지연시키는 것이 좋다.
5. HTTP 메시지
HTTP 메세지로 모든 것을 전송할 수 있다.
HTTP 메세지에는 요청 메세지, 응답메세지가 있다.
메세지구조
- 스타트라인 start-line
- 헤더 header
- 엠티라인 empty line(CRLF): 공백 라인은 빠지면 안됨.
- 메세지 바디 message body
요청 메세지
GET /search?q=hello&hl=ko HTTP/1.1 - start-line
Host: www.google.com - header
- CRLF
요청 메세지도 message body를 가질 수 있음 없으면 생략 가능
응답 메세지
HTTP/1.1 200 OK - start-line
Content-Type: text/html;charset=UTF-8 - header
Content-Length: 3423 - header
- CRLF
<html>...<html> - message body
요청과 응답 모두 HTTP 스펙에 따르면
start-line
*(header-field CRLF) - 여러개의 헤더 필드
CRLF
[message-body] - 생략가능
위와 같은 구조를 따른다.
시작라인
요청 메세지
start-line은 request-line 혹은 status-line이다.
method SP(공백) request-target SP HTTP-version CRLF(엔터)
method
는 GET POST PUT DELETE 등 HTTP 메소드를 말한다. 서버가 수행해야 할 동작을 지정한다.
일단 GET은 리소스 지정 조회 POST는 요청 내역 처리 정도로만 이해하고 추후에 자세히 정리하자.
request-target
은 absolute-path[?query]
의 형식처럼 절대경로로 작성된다.
HTTP-version
은 HTTP 버전을 명시한다.
응답 메세지
HTTP-version SP status-code SP reason-phrase CRLF
위와 같은 형식으로 작성된다.
HTTP-version
은 HTTP 버전을 명시한다.
status-code
는 HTTP 상태 코드를 말하며 요청의 성공 혹은 실패를 나타낸다.
200 성공, 400 클라 오류, 500 서버 내부 오류
reason-phrase
는 상태코드를 사람이 이해할 수 있는 글로 짧게 나타낸 설명이다.
HTTP 헤더
field-name":" OWS field-value OWS (OWS == 띄어쓰기 허용)
field-name과 :은 붙여써야함
field-name
- 대소문자 구분 없음
field-value
- 대소문자 구분함
header는 HTTP 전송에 필요한 모든 부가정보를 나타낸다.
메세지 바디의 내용, 메세지 바디의 크기, 압축, 인증, 요청 클라의 정보 애플리케이션 정보, 캐시 관리 정보 등
바디를 제외하고 필요한 메타데이터가 다 있다.
필요 시 임의의 헤더 추가 가능하며 이때 약속한 클라와 서버만 소통 가능
HTTP 메세지 바디
실제 전송할 데이터다.
HTML 문서, 이미지, 영상, JSON, 등 byte로 표현할 수 있는 모든 것이다.
다시 보는 HTTP의 특징
단순함. 확장 가능.
HTTP는 단순하다. 스펙도 읽어볼만하다
HTTP 메세지도 매우 단순함.
크게 성공하는 표준 기술은 복잡하거나 정교한 기술이 아니라 단순하지만 확장가능한 기술이다.
'Programming > Computer Science' 카테고리의 다른 글
[HTTP] HTTP 메소드 활용, collection, store, POST 기반 설계, PUT 기반 설계 (0) | 2022.04.01 |
---|---|
[HTTP] HTTP 메소드, GET, POST, PATCH, PUT, DELETE, 안전, 멱등 (0) | 2022.03.29 |
[HTTP] URI, 웹 브라우저 요청 흐름 (0) | 2022.02.01 |
[HTTP] 인터넷 통신, IP, TCP, UDP, PORT, DNS (0) | 2022.01.29 |
컴파일타임(compiletime)과 런타임(runtime) (0) | 2021.10.27 |