이 글은 배민 기술이사 김영한 이사님의 인프런 강의 "모든 개발자를 위한 HTTP 웹 기본 지식" 을 기반으로 작성되었습니다. 문제 시 삭제 조치하겠습니다.
목차는 아래와 같습니다.
- 모든 것이 HTTP
- 클라이언트 서버 구조
- Stateful, Stateless
- 비연결성 (Connectless)
- HTTP 메시지
모든 것이 HTTP
일반적으로 휴대폰, 컴퓨터 등에서 필요한 데이터는 서버에 요청하여 받아온다.
네트워크를 통해 서버로부터 데이터를 가져오기 위한 통신으로 크게 HTTP 통신과 Socket 통신 2가지가 있다.
a. HTTP(HyperText Transfer Protocol)
HTTP는 하이퍼 텍스트를 주고 받기 위한 규칙(통신 규약)이다.
b. HTTP 메시지에 모든 것을 전송
1) 거의 모든 형태의 데이터를 전송 할 있습니다.
- HTML, TEXT
- IMAGE, 음성, 영상, 파일
- JSON, XML(API)
2) 서버 간에 데이터를 주고받을 때도 대부분 HTTP 사용
실무에서 통신할 때 TCP 프로토콜을 직접 사용해서 통신하는 경우는 게임 서버를 제외하고는 거의 없다.
c. HTTP 역사
관심있는 분만 읽으시고 넘어가셔도 됩니다.
1) HTTP/0.9 (1991년): GET 메서드만 지원, HTTP 헤더X
2) HTTP/1.0 (1996년): 메서드, 헤더 추가
3) HTTP/1.1 (1997년): 가장 많이 사용, 우리에게 가장 중요한 버전
- RFC2068 (1997) -> RFC2616 (1999) -> RFC7230~7235 (2014)
4) HTTP/2 (2015년): 성능 개선
5) HTTP/3 (진행중): TCP 대신에 UDP 사용, 성능 개선
d. HTTP 기반 프로토콜
1) TCP: HTTP/1.1, HTTP/2
2) UDP: HTTP/3
- 현재 HTTP/1.1 주로 사용, HTTP/2, HTTP/3도 점점 증가
<HTTP 버전 확인해보기>
실제로 F12 를 누르고 Network > protocol 부분을 보면 어떤 HTTP 버전으로 데이터들을 받았는지 알 수 있다.
e. HTTP 특징
HTTP 는 다음 4가지 특징을 가집니다.
1) 클라이언트 서버 구조
2) 무상태 프로토콜(Stateless), 비연결성(Connectless)
3) HTTP 메시지
4) 단순함, 확장 가능
구체적으로 클라이언트 서버 구조가 무엇인지 확인해봅시다.
클라이언트 서버 구조
Request & Response 구조
- 클라이언트는 서버에 요청을 보내고 응답을 대기
- 서버가 요청에 대한 결과를 만들어서 응답
클라이언트와 서버를 개념적으로 분리하는 것이 중요합니다!!
1) 클라이언트 - UI, UX, 사용성에 집중
2) 서버 - 비즈니스 로직, 데이터 처리에 집중
→ 클라이언트, 서버는 각각 독립적으로 진화할 수 있습니다.
[참고] https://bentist.tistory.com/35
[참고] https://kotlinworld.com/75
Stateful, Stateless
a. 무상태 프로토콜(Stateless)
서버가 클라이언트의 상태를 보존하지 않습니다.
- 장점: 서버 확장성 높음(스케일 아웃)
- 단점: 클라이언트가 데이터를 추가로 전송해야 합니다.
b. Stateful, Stateless 차이
b - 1. 상태 유지 - Stateful
아래의 경우를 확인해봅시다. 고객이 클라이언트이고 점원이 서버라고 보면 됩니다.
1) 상태 유지 - Stateful
2) 상태 유지- Stateful, 점원이 중간에 바뀌면?
3) 상태유지 - Stateful, 정리
그렇다면 같은 상황에서 Stateless 라면 어떨까요?
b-2. 무상태 - Stateless
1) 무상태 - Stateless
이런 식으로 클라이언트가 데이터를 추가로 보내주어야 합니다.
2) 무상태 - Stateless, 점원이 중간에 바뀌면?
클라이언트가 데이터를 추가로 보내주어야 하는 대신 서버가 바뀌어도 문제없이 실행될 수 있지요
<정리>
1) Stateful(상태 유지) - 중간에 다른 점원으로 바뀌면 안된다. (중간에 다른 점원으로 바뀔 때, 상태 정보를 다른 점원에게 미리 알려줘야 한다)
2) Stateless(무상태) - 중간에 다른 점원으로 바뀌어도 된다.
- 갑자기 고객이 증가해도 점원을 대거 투입할 수 있다.
→ 즉, 갑자기 클라이언트 요청이 증가해도 서버를 대거 투입할 수 있다.
- Stateless는 응답 서버를 쉽게 바꿀 수 있다. → 무한한 서버 증설 가능
c. 상태 유지 - Stateful
1) 항상 같은 서버가 유지되어야 합니다.
클라이언트A는 서버1과 계속 통신을 유지해야한다.
클라이언트A가 서버1에게 노트북 정보를 보내고, 서버로 부터 응답을 받고 2개라는 정보를 보내고 서버로부터 응답을 받는다. 서버1은 클라이언트A가 요청한 노트북, 2개라는 상태를 모두 유지하고 있는 상태가 된다.
2) 중간에 서버가 장애나면?
서버1이 장애가 나면, 클라이언트A는 결제를 처음부터 다시 해야하는 문제가 생긴다.
d. 무상태 - Stateless
1) 아무 서버나 호출해도 된다.
클라이언트A가 모든 정보(노트북, 2개)를 담아서 서버1에 요청을 하면, 서버1는 상태를 보관하지 않고 응답만 한다.
2) 중간에 서버가 장애나면?
만약 서버1에서 장애가 나면, 중계 서버가 서버 2번으로 요청을 던진다.
서버2도 마찬가지로 클라이언트A의 상태를 보관하지 않고 응답만 한다.
3) 스케일 아웃 - 수평 확장 유리
Stateless 에서의 가장 큰 장점입니다!
예를 들어, 이벤트를 하는 경우 서버를 확장시켜 놓으면 된다.
<실무 한계>
하지만 Stateless로 설계 할 수 있는 경우도 있고 없는 경우도 있습니다.
그러므로 가능한 무상태로 설계하고, 상태 유지는 최소한만 사용해야 합니다!
예를 들면 아래와 같죠.
1) 무상태 - 로그인이 필요없는 단순한 서비스 소개 화면
2) 상태 유지 - 로그인
- 로그인한 사용자의 경우, 로그인 했다는 상태를 서버에 유지
- 일반적으로 브라우저 쿠키와 서버 세션 등을 사용해서 상태 유지
비연결성 (Connectless)
먼저 연결을 유지하는 모델에서의 예시를 봅시다.
a. 연결을 유지하는 모델
TCP/IP 는 연결을 유지하는 모델입니다.
1) 클라이언트1 & 서버 TCP/IP 연결
클라이언트1은 서버와 연결된 후, 요청과 응답을 주고 받는다.
현재 클라이언트 1은 서버와 연결이 유지된 상태이다.
2) 클라이언트2 & 서버 TCP/IP 연결
클라이언트2는 서버와 연결된 후, 요청과 응답을 주고 받는다.
현재 클라이언트1, 2는 서버와 연결이 유지된 상태이다.
3) 클라이언트3 & 서버 TCP/IP 연결
클라이언트3은 서버와 연결된 후, 요청과 응답을 주고 받는다.
현재 클라이언트1, 2, 3은 서버와 연결이 유지된 상태이다.
4) 클라이언트1 & 서버 요청, 응답
클라이언트1은 이미 연결된 상태이므로 TCP/IP 연결을 다시 하지 않고, 요청과 응답을 주고 받는다.
현재 클라이언트 1, 2, 3은 서버와 연결이 유지된 상태이다.
그렇다면 연결을 유지하지 않는 모델의 예를 봅시다.
b. 연결을 유지하지 않는 모델
1) 클라이언트1 & 서버 TCP/IP 연결
클라이언트1은 서버와 연결된 후, 요청과 응답을 주고 받는다.
현재 클라이언트1은 서버와 연결이 유지된 상태이다.
2) 클라이언트1 & 서버 TCP/IP 연결 종료
클라이언트1은 필요한 요청, 응답이 끝나면 서버와 연결을 종료한다.
현재 서버와 연결이 유지된 클라이언트는 없다.
3) 클라이언트2 & 서버 TCP/IP 연결
클라이언트2는 서버와 연결된 후, 요청과 응답을 주고 받은 후, 연결을 종료한다.
현재 서버와 연결이 유지된 클라이언트는 없다.
4) 클라이언트3 & 서버 TCP/IP 연결
클라이언트3은 서버와 연결된 후, 요청과 응답을 주고 받은 후, 연결을 종료한다.
현재 서버와 연결이 유지된 클라이언트는 없다.
4) 클라이언트1 & 서버 TCP/IP 연결
필요한 자원이 있으면, 클라이언트1은 서버와 연결된 후, 요청과 응답을 주고 받은 후, 연결을 종료한다.
현재 서버와 연결이 유지된 클라이언트는 없다.
c. 비연결성(Connectless)
HTTP는 기본이 연결을 유지하지 않는 모델입니다.
- 일반적으로 초 단위 이하의 빠른 속도로 응답
- 1시간 동안 수천 명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청은 수십개 이하로 매우 작음
e.g 웹 브라우저에서 계속 연속해서 검색 버튼을 누르지는 않음, 같은 초 단위에 검색하는 사용자가 많지 않음
- 서버 자원을 매우 효율적으로 사용
d. 비 연결성 - 한계와 극복
그런데 HTTP 의 Connectless 에서도 한계가 있습니다.
<한계>
1) TCP/IP 연결을 새로 맺어야 함 → 3 way handshake 시간 추가
e.g. 검색을 해서 보다가 어떤 게시글을 또 새로 누르는 경우, TCP/IP 연결을 새로 맺어야함
2) 웹 브라우저로 사이트를 요청하면 HTML, 자바스크립트,css, 추가 이미지 등 수많은 자원이 함께 다운로드
→ 자원을 다운로드 받을 때마다 3 way handshake를 해야 하는 문제..
<극복>
1) 지금은 HTTP 지속 연결(Persistent Connections)로 문제 해결
2) HTTP/2, HTTP/3 에서 더 많은 최적화
e. HTTP 초기 - 연결, 종료 낭비
연결 → 자원 요청/HTML 응답 → 종료
필요한 자원이 있을 때마다, 위 과정을 무한 반복한다.
f. HTTP 지속 연결(Persistent Connections)
연결 → 자원 요청/HTML 응답 → 자원 요청/자바스크립트 응답 → ... → 종료
필요한 자원이 있으면 연결을 유지하고 더이상 필요한 자원이 없을 때 연결을 종료한다.
- 매커니즘 마다 연결 지속 시간의 차이는 있으나, 보통 HTML 한 페이지에 필요한 자원을 모두 받을 때까지는 연결을 유지한다.
g. Stateless를 기억하자
서버 개발자들이 어려워하는 업무는 같은 시각에 딱 맞춰 대용량 트래픽이 발생하는 경우입니다.
e.g. 선착순 이벤트, 명절 KTX 예매, 수강 신청 등 → 수만명 동시 요청
하지만, 최대한 Stateless 하게 설계하는 것이 중요합니다!!
- 보통 첫 페이지는 로그인도 필요없는 정적 페이지(순수 HTML)을 뿌린 다음, 이벤트 참여 버튼을 누르게 하는 방식으로 구현.
- 이벤트 참여 버튼을 누른 후에 로그인이 필요하도록 만듭니다.
<Stateless와 Connectionless의 차이>
1) Stateless - 클라이언트 서버 사이에 상태를 유지하지 않는다
2) Connectionless - TCP/IP 커넥션 연결을 지속하지 않는다
HTTP 메시지
a. 모든 것이 HTTP (복습)
먼저 HTTP 에 대해 학습한 내용을 복습해봅시다. HTTP 메시지에 모든 것을 전송할 수 있다고 했습니다.
1) 거의 모든 형태의 데이터 전송 가능
- HTML, TEXT
- IMAGE, 음성, 영상, 파일
- JSON, XML(API)
2) 서버 간에 데이터를 주고받을 때도 대부분 HTTP 사용
b. HTTP 요청 메시지와 HTTP 응답 메시지
보는 것과 같이, HTTP 요청 메시지와 HTTP 응답 메시지는 형태가 조금 다릅니다.
c. HTTP 메시지 (HTTP 요청 메시지와 HTTP 응답 메시지)의 구조
c-1. HTTP 메시지 구조
1) start-line: 시작 라인
2) header: 헤더
3) empty line: 공백 라인 - 무조건 있어야 함
4) message body
사실 HTTP 요청 메시지와 HTTP 응답 메시지는 start-line 부분만 차이가 있습니다.
요청 메시지 (request mesage) 에서는 request-line 이며, 응답 메시지 (response message)은 status-line 입니다.
c-2. HTTP 요청 메시지 구조
1) start-line - http 메서드/path/query string/http 버전
2) header - 호스트(도메인명)
3) empty line
4) message body - 전송할 데이터가 없으면, 공백으로
당연히 HTTP 요청 메시지도 body 본문을 가질 수 있습니다
c-3. HTTP 응답 메시지 구조
1) start-line - http 버전/ 상태코드
2) header -Content-Type, Content-Length
3) empty line -
4) message body - html
d. 시작 라인(start-line) - 요청 메시지
start-line = request-line / status-line ( Request message 이므로 bold 체 된 request-line 입니다. )
request-line = method
request-target
HTTP-version
CRLF(엔터)
- method: HTTP 메서드 (여기서는 GET)
- request-target: 요청 대상 (search?q=hello&hl=ko)
- HTTP-version: HTTP 버전 (HTTP/1.1)
1) 요청 메시지 - HTTP 메서드
서버가 수행해야 할 동작을 지정합니다.
종류: GET, POST, PUT, DELETE...
- GET: 리소스 조회
- POST: 요청 내역 처리
2) 요청 메시지 - 요청 대상
absoulte-path[?query] (절대경로[?쿼리])
- 절대 경로 = "/" 로 시작하는 경로
(참고) *, http://...?x=y 와 같이 다른 유형의 경로지정 방법도 있음
3) 요청 메시지 - HTTP 버전
이제 Response message 의 경우를 봅시다.
e. 시작 라인(start-line) - 응답 메시지
start-line = request-line / status-line (Response message 이므로 start-line 이 status-line)
status-line = HTTP-version
status-code
reason-phrase
CRLF(엔터)
1) HTTP-version(HTTP 버전) (HTTP/1.1)
2) status-code(HTTP 상태 코드) 중요!! (200)
요청 성공/실패 의 정보를 가집니다.
- 200: 성공
- 400: 클라이언트 요청 오류
- 500: 서버 내부 오류
3) reason-phrase(이유 문구) (OK)
사람이 이해할 수 있는 짧은 상태 코드 설명글
f. HTTP 헤더
header-field =
field-name ":" OWS field-value OWS (OWS:띄어쓰기 허용)
- field-name은 대소문자 구분X, field-value는 대소문자 구분O
<용도>
HTTP 전송에 필요한 모든 부가정보
e.g. 메시지 바디 내용, 메시지 바디 크기, 압축, 인증, 요청 클라이언트(브라우저) 정보, 서버 애플리케이션 정보, 캐시 관리 정보...
- 표준 헤더가 너무 많기 때문에 모두 설명할 수는 없습니다.
- 필요시 임의의 헤더를 추가할 수도 있어요.
g. HTTP 메시지 바디
<용도>
실제 전송할 데이터
- HTML 문서, 이미지, 영상, JSON 등등 byte로 표현할 수 있는 모든 데이터 전송 가능
지금까지 HTTP 기본에 대해 알아보았습니다. 정리하면 아래와 같습니다.
<HTTP 정리>
- HTTP 메시지에 모든 것을 전송
- HTTP 역사: HTTP/1.1을 기준으로 학습(HTTP/2,3은 성능 최적화 부분)
- 클라이언트 서버 구조
- 무상태 프로토콜(Stateless)
- HTTP 메시지
- 단순함, 확장 가능
현재 우리가 개발할 거의 모든 통신은 HTTP 프로토콜입니다. 다음 글에서는 HTTP 메서드에 대해 조금 더 자세히 알아봅시다.
'Computer Science > Http 웹 지식' 카테고리의 다른 글
6. HTTP 상태코드 - HTTP 웹 기본 지식 (0) | 2023.01.08 |
---|---|
5. HTTP 메서드 활용 - HTTP 웹 기본 지식 (0) | 2023.01.08 |
4. HTTP 메서드 - HTTP 웹 기본 지식 (1) | 2023.01.08 |
2. URI와 웹 브라우저 요청 흐름 - HTTP 웹 기본 지식 (1) | 2023.01.06 |
1. 인터넷 네트워크 - HTTP 웹 기본 지식 (0) | 2023.01.06 |