HTTP
HyperText Transfer Protocol
HTTP의 시작은 HyperText, 즉 HTML, 문서간에 링크를 통해서 연결할 수 있는 하이퍼 텍스트 문서를 전송하는 것으로 시작됨.
지금은 모든 것을 HTTP 프로토콜에 담아서 전송한다!
- HTML, TEXT 뿐만아니라
- 이미지, 음성, 영상, 파일
- JSON, XML(API)
- 거의 모든 형태의 데이터가 전송 가능하다.
- 서버간에 데이터를 주고 받을 때도 대부분 HTTP를 사용한다.
- 실무에서 서버간에 TCP를 직접 연결하는 경우 거의 없다. 대부분 HTTP 사용함
- 게임서버 정도의 특수한 경우에만 TCP를 직접 연결한다.
- 지금은 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의 스펙을 잘 알면된다. 2와 3은 성능개선이므로 1.1과 큰 차이 없다.
기반 프로토콜
- TCP : HTTP/1.1, HTTP/2
- UDP : HTTP/3
- 현재 HTTP/1.1주로 사용
- HTTP/2, HTTP/3도 점점 증가
HTTP 특징
- 클라이언트 서버 구조
- 무상태 프로토콜(Stateless), 비연결성
- HTTP 메시지를 통해 통신
- 단순함, 확장 가능
클라이언트 서버 구조
- Request, Response 구조
- 클라이언트는 서버에 요청을 보내고, 응답을 대기
- 서버가 요청에 대한 결과를 만들어서 응답

위의 특징은 굉장히 표면적인 것이고, 실제로 중요한 것은 클라이언트와 서버로 역할을 분리한 것이다.
이전까지는 클라이언트와 서버를 따로 분리하지 않았음. 이를 개념적으로 분리해냄. 비즈니스 로직이나 데이터같은 것들은 서버에 모두 밀어넣는다. 클라이언트는 UI(화면)/UX(사용성)에 집중한다.
➡ 이런식으로 하면 클라이언트와 서버가 각각 독립적으로 발전할 수 있다.
무상태 프로토콜 (Stateless)
- 서버가 클라이언트의 상태를 보존 X
- 장점 : 서버의 확장성 높음(스케일 아웃)
- 단점 : 클라이언트가 추가 데이터 전송
Stateful, Stateless 차이
상태 유지 - Stateful

상태 유지 - Stateful, 점원이 중간에 바뀌는 경우

상태 유지 - Stateful, 정리

무상태 - Stateless

무상태 - Stateless, 점원이 중간에 바뀌는 경우

정리
- 상태유지 : 중간에 다른 점원으로 바뀌면 안된다.
(중간에 다른 점원으로 바뀔 때 상태정보를 다른 점원에게 미리 알려줘야한다.)
- 무상태 : 중간에 다른 점원으로 바뀌어도 된다.
- 갑자기 고객이 증가해도 점원을 대거 투입할 수 있다.
- 갑자기 클라이언트 요청이 증가해도 서버를 대거 투입할 수 있다.
- 무상태는 응답 서버를 쉽게 바꿀 수 있다 ➡ 무한한 서버 증설 가능
확장 가능


- 유지되던 상태정보가 다 날라가버리므로 처음부터 다시 요청해야한다.

- 애초에 요청할 때 필요한 데이터를 다 담아서 보내기 때문에 아무 서버나 호출해도 상관없다.


Stateless 실무 한계
- 모든 것을 무상태로 설계할 수 있는 경우도 있고 없는 경우도 있다.
- 무상태
- 예) 로그인이 필요 없는 단순한 서비스 소개 화면
- 상태 유지
- 로그인한 사용자의 경우 로그인 했다는 상태를 서버에 유지
- 일반적으로 브라우저 쿠키와 서버 세션등을 사용해서 상태 유지
- 상태 유지는 최소한만 사용
➕
- Stateless의 경우 요청할 때 데이터를 너무 많이 보낸다.
비연결성(Connectionless)
연결을 유지하는 모델



- TCP/IP의 경우 기본적으로 연결을 유지한다.
- 클라이언트 1,2는 요청을 보내지 않더라도 계속 연결을 유지하고 있다.
- 이러한 경우 연결을 유지하는 서버의 자원이 계속 소모가 되는 것이다.
연결을 유지하지 않는 모델




- 실제로 요청을 주고 받을 때만 연결을 유지함으로써 서버가 연결을 유지하는 자원을 최소한으로 줄여준다.
- 최소한의 자원으로 서버 유지 가능
HTTP 통신 특징
- HTTP는 기본이 연결을 유지하지 않는 모델이다.
- 일반적으로 초 단위 이하의 빠른 속도로 응답한다.
- 1시간 동안 수천명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청은 수십개 이하로 매우 작다. 수천명이 동시에 클릭하지 않는다. 실제로 1시간을 초단위로 나누면은 초당 동시요청수는 얼마되지 않는다.
- 이러한 경우 연결을 유지하지 않도록 설계하면 초당 몇십개의 연결만 유지하면 된다. 한시간동안 수천개의 연결을 유지할 필요없다.
- 서버 자원을 매우 효율적으로 사용할 수 있다.
한계와 극복
- TCP/IP 연결을 매번 새로 맺어야한다. - 3 way handshake 시간 추가
- 웹 브라우저로 사이트를 요청하면 HTML 뿐만 아니라 자바스크립트, css, 추가 이미지 등 수 많은 자원이 함께 다운로드된다.
- 해당 자원들 각각 보낼때마다 연결끊고 다시 연결하고를 반복하는 것은 비효율적이다.
- 지금은 HTTP 지속 연결(Persistent Connections)로 문제를 해결
- HTTP/2, HTTP/3에서 더 많은 최적화가 이루어짐
HTTP 초기 - 연결, 종료 낭비

HTTP 지속 연결(Persistence Connections)

Stateless를 기억하자!!
서버 개발자들이 어려워하는 업무
- 정말 같은 시간에 딱 맞추어 발생하는 대용량 트래픽
- 예) 선착순 이벤트, 명절 KTX 예약, 학과 수업 등록
- 예) 저녁 6:00 선착순 1000명 치킨 할인 이벤트 ➡ 수만명 동시 요청
- 이런경우 진짜 비연결성 이런게 소용없다 🤣 동시요청이 수만건되니까
따라서 무조건 최대한 Stateless하게 설계해야한다!!!
그래야만 이런 대용량 트래픽이 올때에도 서버를 확 늘려서 (Scale out) 대응할 수 있는 부분이 많아진다.
HTTP 메시지
HTTP 요청메시지와 응답메시지의 구조가 조금 다르다.

- 시작라인, 헤더, 공백(필수), 메시지 바디로 구성

- 공백은 요청 응답에 필수적으로 들어간다.
시작 라인
- 크게 request-line / status-line이 있다.
- 요청 메시지는 request-line, 응답 메시지는 status-line
요청 메시지
- request-line = method SP(공백,space) request-target SP HTTP-version CRLF(엔터)

- HTTP method : GET
- request-targer(요청 대상) : (/search?q=hello&ko)
- HTTP Version : HTTP/1.1
응답 메시지
- status-line = HTTP-version SP status-code SP reason-phrase CRLF
- HTTP version
- status-code : 요청 성공, 실패를 나타낸다.
- 200: 성공
- 400: 클라이언트 요청 오류
- 500: 서버 내부 오류
- reason-phrase : 사람이 이해할 수 있는 짧은 상태 코드 설명 글
HTTP 헤더
- header-field = field-name ":" OWS field-value OWS (OWS: Optional White Space, 띄어쓰기 허용)
- field-name은 대소문자 구분 없음, value는 구분
- HTTP 전송에 필요한 모든 부가정보
- 예) 메시지 바디의 내용, 메시지 바디의 크기, 압축, 인증, 요청 클라이언트(브라우저) 정보, 서버 애플리케이션 정보, 캐시 관리 정보
- 표준 헤더가 너무 많다.
- 필요시 임의의 헤더 추가 가능하다.
HTTP 메시지 바디
- 실제 전송할 데이터
- HTML 문서, 이미지, 영상, JSON 등등 byte로 표현할 수 있는 모든 데이터 전송 가능
단순함 확장 가능
HTTP 스펙보면 굉장히 단순하다는 것을 알 수 있다.
- HTTP는 단순하다.
- HTTP 메시지도 매우 단순하다. (start-line, header, CRLF, body로 단순 구성)
- 크게 성공하는 표준 기술은 단순하지만 확장 가능한 기술
해당 게시글은 김영한님의 <모든 개발자를 위한 HTTP 웹 기본지식> 인프런 강의를 듣고 정리한 내용입니다.