모든 것이 HTTP
HTTP(Hyper Text Transfer Protocol)
HTTP는 'Hyper Text Transfer Protocol' 말 그대로 '하이퍼텍스트 전송 통신규약'이다.
즉, 문서 간의 링크를 통해서 연결할 수 있는 html을 전송하는 프로토콜로 처음 시작하였다.
하지만 현재는 모든 것을 http 메시지에 담아서 전송한다.
- HTML, TEXT
- IMAGE, 음성, 영상, 파일
- JSON, XML(API)
- 등등 거의 모든 형태의 데이터 전송 가능
- 서버 간에 통신을 주고 받을 때도 대부분 HTML 사용
- 서버간에 데이터를 주고 받을 때도 대부분 HTTP 사용 지금은 HTTP 시대!
이렇듯 모든 것이 HTTP로 주고 받기 때문에
현재 HTTP가 가지는 의미는 '인터넷에서 데이터를 주고 받을 수 있는 프로토콜'이다.
HTTP 역사
- HTTP/0.9 1991년 : GET 메서드만 지원, HTTP 헤더 X
- HTTP/1.0 1996년 : 메서드, 헤더 추가
- HTTP/1.1 1997년 : 가장 많이 사용, 우리에게 가장 중요한 버전
- RFC2068(1997) -> RFC2616(1999) -> RFC7230~7235(2014)
- 1997년 1.1 버전 이후 개정본
- HTTP/2.0 2015년 : 성능 개선
- HTTP/3 진행중 : TCP 대신에 UDP 사용, 성능 개선
HTTP의 역사를 보자면 HTTP 2와 3 버전이 나와있는데도
1.1 버전이 가장 중요하다고 강조하는 이유는 뭘까?
이유는 현재 가장 많이 사용하기도 하지만
1.1 버전 스펙에 대부분의 기능이 다 들어있으며 2, 3 버전은 성능 개선에 초점을 맞췄기 때문이다.
1.1 버전을 잘 배워놓으면 2, 3은 성능만 개선해놓은 것이기 때문에 괜찮다.
기반 프로토콜
- TCP : HTTP/1.1, HTTP/2
- UDP : HTTP/3
- 현재 HTTP/1.1 주로 사용
- HTTP/2, HTTP/3도 점점 증가
여기서 짚고 넘어가야 할 것이 HTTP/3의 기반 프로토콜이 UDP인 것이다.
여기서 TCP가 안정적이고 좋은 것이 아닌가 하는 의문이 생길 수 있다.
TCP는 3 way handshake 과정도 있고 기본적으로 안에 데이터도 많기 때문에
기본적인 메커니즘 자체가 속도가 빠르지는 않다.
따라서 HTTP3는 UDP프로토콜을 기반으로 하여 애플리케이션 레벨에서 새로 설계 후 성능을 최적화하여 나온 것이다.
개발자 도구에서 네트워크(Network) 창에 프로토콜(Protocol)을 확인해보자.
프로토콜(Protocol)이 안보이면 우 클릭 후에 체크를 해주어야한다.
네이버 메인화면에서의 개발자도구-네트워크 창의 일부분인데
h2(HTTP/2)가 많이 보이는 모습이다.
구글로 가보면 h3(HTTP/3)도 많이 보이는데 확실히 점점 증가하고 있다는 것이 사실이다.
클라이언트 서버 구조
- Request, Response 구조
- 클라이언트는 서버에 요청을 보내고, 응답을 대기
- 서버가 요청에 대한 결과를 만들어서 응답
- 클라이언트는 서버의 응답 결과를 열어서 동작을 하게 됨
표면적으로는 단순한 Request, Response 구조이다.
여기서 중요하게 생각해야 할 것은 클라이언트와 서버의 분리된 구조이다.
클라이언트와 서버를 분리하는 것이 왜 중요할까?
바로 클라이언트와 서버가 각각의 역할에 독립적으로 집중하고 진화하기 위해서이다.
복잡한 비즈니스 로직과 데이터 등은 서버에 다 밀어넣어 놓고
클라이언트는 사용성 등 UI/UX에 집중을 하는 것이다.
이렇게 하면 클라이언트는 복잡한 비즈니스 로직, 데이터 등을 다룰 필요가 없고
단순하게 사용성에 집중하여 UI/UX를 어떻게 그릴지에 집중을 할 수 있다.
예를 들어서 클라이언트가 iPhone이라고 한다면 UI/UX를 그리는데 집중을 하고
복잡한 비즈니스 로직은 서버에서 처리하도록 맡길 수 있다.
반대로 서버의 예를 들자면 어떤 회사가 갑자기 떡상해서 트래픽이 100배 이상 폭주했다고 하자
그러면 클라이언트에서는 손댈 곳이 없고 서버에서 처리하여야 한다.
서버는 아키텍처를 어떻게 할지, 백엔드 기술로 어떻게 대용량 트래픽을 고도화하고 처리할지 그것만 고민하면 된다.
ex) php를 쓴다면 java로 언어를 변경한다 등
클라이언트는 몰라도 되는 것들이다.
따라서 클라이언트와 서버의 분리는
양쪽이 독립적으로 진화하고 집중할 수 있다는 점에서 상당히 중요하다.
무상태 프로토콜
스테이트리스(Stateless)
- 서버가 클라이언트의 상태를 보존X
- 장점 : 서버 확장성이 높음(스케일 아웃)
- 단점 : 클라이언트가 추가 데이터 전송
Stateful, Stateless 차이
Stateful(상태유지)와 Statelee(무상태)의 차이 비교에 앞서 예시를 한번 보자.
먼저 상태유지이다.
예시에서 보듯이 상태유지에서 한계는 너무나 뚜렷하다.
서버가 클라이언트의 상태를 보존한다는 것인데
쉽게 말해서, 클라이언트가 통신 하던 서버가 장애가 나서 다른 서버와 재통신시 처음부터 다시 요청을 해야한다는 것이다.
원래 서버와 하던 요청을 다른 서버와 이어서 하게 된다면
다른 서버에서는 원하는 데이터가 없기 때문에 문제가 생긴다. 문맥이 없어지는 것이다.
이번엔 무상태 예시를 보자.
무상태에서는 필요한 데이터를 그때 그때 고객이 다 넘겨준다.
예시에서 보듯이 필요한 데이터를 다 넘기기 때문에 중간에 점원이 바껴도 문제가 되지 않는다.
따라서 클라이언트가 통신하던 서버가 갑자기 장애가 나서 다른 서버와 통신을 하게 되어도
클라이언트는 필요한 데이터를 다 넘기기 때문에 다른 서버와도 통신이 가능한 것이다.
정리를 하자면
- Stateful(상태유지)
- 중간에 다른 서버로 바뀌면 안된다.(중간에 다른 서버로 바뀌게 된다면 상태 정보를다른 서버에게 알려줘야 함)
- Stateless(무상태)
- 중간에 다른 서버로 바껴도 된다.
- 갑자기 클라이언트 요청이 증가해도 서버를 대거 투입할 수 있다.
- 무상태는 응답 서버를 쉽게 바꿀 수 있다. => 무한한 서버 증설 가능
그림으로 다시 한번 정리를 해보자.
그림처럼 Stateful(상태유지)에서 클라이언트A는 항상 같은 서버와 통신을 해야한다.
중간에 서버가 장애가 나면 다른 서버와 통신이 가능하긴 하지만
처음부터 요청을 다시 해야한다.
그림처럼 Stateless(무상태)에서는 클라이언트가 애초에 요청할 때부터 필요한 데이터를 다 담아서 보낸다.
따라서 중간에 갑자기 통신하던 서버가 장애가 나도
클라이언트A의 요청은 중계서버에서 2번 서버로 보내는데
이미 그 요청에는 필요한 데이터가 다 포함되어 있기 때문에 아무런 문맥 없이 요청을 처리하고 응답이 가능한 것이다.
이러한 Stateless(무상태)의 큰 장점은 서버를 확 늘려버릴 수 있다는 것이다.
***스케일 아웃(Scale-out)은 장비를 추가해서 서버를 확장하는 방식이다.
***참고로 스케일 업(Scale-up)은 기존의 서버를 보다 높은 사양으로 업그레이드하는 방식
그림에서 보듯이 Stateless(무상태)는 서버의 수평 확장에 유리하다.
클라이언트의 요청이 몰려들 것으로 예상되는 큰 이벤트 페이지가 있으면 백엔드 설계에서 장비를 수십대 확 늘려버릴 수가 있다.
하지만 Stateless에도 한계는 분명 존재한다.
Stateless 실무 한계
- 모든 것을 Stateless(무상태)로 설계할 수 있는 경우도 있고 없는 경우도 분명히 있다.
- 무상태
- 로그인이 필요없는 단순한 서비스 소개 화면
- 상태유지
- 로그인
- 로그인한 사용자의 경우 로그인 했다는 상태를 서버에 유지
- 일반적으로 브라우저 쿠기와 서버 세션 등을 사용해서 상태 유지
- Stateful(상태유지)는 최소한만 사용
- 꼭 필요한 경우에만 어쩔 수 없이 사용해야 한다고 이해하자.
- 무상태는 전송되는 데이터량이 많다는 단점이 있다.
- 하지만 웹 설계에서는 최대한 무상태로 설계한다.
- 정말 어쩔 수 없는 경우에 한해서만 Stateful(상태유지)을 한다.
비연결성(Connectionless)
TCP/IP는 기본적으로 연결을 유지한다.
연결을 유지하는 모델
연결을 유지하는 모델에서는
클라이언트 1, 2, 3이 각각 요청을 보낼 때
서버에서는 클라이언트 1, 2, 3에 대한 각각의 응답이 끝나도 각각의 연결을 유지한다.
클라이언트 3이 요청할 때 1, 2가 놀고 있어도 서버가 연결을 유지하고 있다는 것이다.
이는 서버 자원이 크게 소모되는 단점이 있다.
연결을 유지하지 않는 모델
연결을 유지하지 않으면 요청할 때만 연결을 하고 응답 후 연결을 끊는다.
따라서 서버의 자원을 최소한으로 줄일 수 있다.
서버가 동시에 유지해야하는 자원을 요청할 때만 받고 응답 후 끊어버리기 때문에 최소한의 자원으로 서버를 유지할 수 있게 된다.
비연결성
- HTTP는 기본이 연결을 유지하지 않는 모델
- 일반적으로 초 단위 이하의 빠른 속도로 응답
- 1시간 동안 수천 명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청은 수십개 이하로 매우 작다.
- ex) 웹 브라우저에서 계속 연속해서 검색 버튼을 누르지는 않는다.
- 서버의 자원을 매우 효율적으로 사용할 수 있다.
비연결성 한계와 극복
- 한계
- TCP/IP 연결을 새로 맺어야 함 - 3 way handshake 시간 추가
- 웹 브라우저로 사이트를 요청하면 HTML 뿐만 아니라 자바스크립트, css, 추가 이미지 등 수 많은 자원이 함께 다운로드 됨
- 극복
- 지금은 HTTP 지속연결(Persistent Connections)로 문제 해결
- HTTP/2, HTTP/3에서 더 많은 최적화
내부 매커니즘에 따라 다르겠지만
웬만한 HTML 페이지 하나 받을 때까지 지속 연결을 유지한다.
HTTP/2, HTTP/3에서는 이런 속도를 더 최적화하였다.
심지어 HTTP/3에서는 UDP 프로토콜로 연결 자체 속도도 줄여버렸다.
스테이트리스(Stateless)를 기억하자!
서버 개발자들이 어려워하는 업무
- 정말 딱 같은 시간에 맞추어 발생하는 대용량 트래픽
- ex) 선착순 이벤트, 명절 KTX 예약, 학과 수업 등록 등
- ex) 저녁 6:00 선착순 1000명 치킨 할인 이벤트 => 수 만명 동시 요청
수만명 동시 요청시 비연결성 이런게 소용이 없다.
정확히 같은 시간에 동시에 다 몰려오기 때문에 최대한 Stateless하게 설계하는 것이 중요하다.
Stateless 설계를 하면 대용량 트래픽이 올 때도 서버를 확 늘려서 대응을 할 수 있는 부분이 많아진다.
보통 이벤트 설계에서 첫페이지는 로그인도 필요없는 정적 페이지를 하나 뿌린다.
그 첫 페이지는 아무 상태도 없이 순수한 HTML을 하나 딱 둔다.
사람들이 거기서 약간 놀기도 하고 다른거 보기도 하면서
이벤트 참여 버튼을 누르게 한다거나 이런식으로 설계한다.
그러면 사람들이 좀 보다가 누르고 이런 것들이 생기니까 아무래도 부하가 덜 생기기 때문이다.
중요한 것은 Stateless 설계를 한다는 것!
HTTP 메시지
HTTP의 요청 메시지와 응답 메시지 구조에 대해서 알아보자.
HTTP는 요청 메시지와 응답 메시지가 약간! 다르지만
메시지 구조 자체는 똑같다. 그림을 보자.
여기서 공백라인(CRLF)는 무조건 들어가야 하며
HTTP 요청 메시지에 body는 들어가도 그만 안들어가도 그만이다.
공식 스펙을 보아도 그림처럼 단순하게 시작라인-헤더-공백라인-바디의 구조를 가지고 있다.
하나씩 뜯어서 보자.
시작라인
요청메시지
- start-line = request-line / status-line
- 요청메시지의 시작라인은 메시지 성격 그대로 요청라인(request-line)이다.
- requeset-line = method SP(공백, 스페이스) request-target SP HTTP-version CRLF(엔터)
- request-line에는 HTTP 메서드, 요청대상(path), HTTP 버전 순으로 세개가 들어간다.
- HTTP 메서드
- GET, POST, PUT, DELETE 등 (뒤에서 다룬다)
- 요청대상(/search?q=hello&hl=ko)
- 절대경로("/"로 시작하는 경로)(absolute-path)[?query]로 시작한다.
- 참고로 다른 유형의 경로 지정 방식도 있지만 절대 경로로 시작한다고 이해하자. ex) *, http://..?x=y 등
- HTTP 버전
- request-line에는 HTTP 메서드, 요청대상(path), HTTP 버전 순으로 세개가 들어간다.
응답메시지
- start-line = request-line / status-line
- 응답메시지의 시작라인은 status-line이다.
- status-line = HTTP 버전 SP status-code SP reason-phrase CRLF
- status-line에는 HTTP 버전, 상태코드 , 이유문구 순으로 세개가 들어간다.
- HTTP 버전
- HTTP 상태코드 : 요청 성공, 실패를 나타닌다.
- 200 : 성공
- 400 : 클라이언트 요청 오류
- 500 : 서버 내부 오류
- 이유문구 : 사람이 이해할 수 있는 짧은 상태 코드 설명 글(ex) OK 등)
- status-line에는 HTTP 버전, 상태코드 , 이유문구 순으로 세개가 들어간다.
HTTP 헤더
- header-field = field-name":" OWS field-value OWS
- field-name은 대소문자 구분 없음
- field-value는 대소문자 구분함
- OWS는 띄어쓰기 허용(해도 그만 안해도 그만)
- HOST : << 이건 안됨. 중간에 띄우면 안되기 때문.
- HTTP 헤더의 용도
- 메시지 바디를 빼고 필요한 메타데이터 정보가 다 들어있다.(HTTP 전송에 필요한 모든 부가정보)
- ex) 메시지 바디의 형식(HTML 등), 메시지 바디의 크기, 압축, 인증, 요청 클라이언트(브라우저 정보), 서버 애플리케이션 정보, 캐시관리 정보 등등
- 표준 헤더가 너무 많음
- 필요시 임의의 헤더 추가 가능
- ex) helloworld:hihi
- 물론 임의의 헤더 추가시 약속한 클라이언트와 서버만 이해 함.
- 메시지 바디를 빼고 필요한 메타데이터 정보가 다 들어있다.(HTTP 전송에 필요한 모든 부가정보)
HTTP 바디
- HTTP 바디의 용도
- 실제 전송할 데이터
- HTML 문서, 이미지, 영상, JSON 등등 byte로 표현할 수 있는 모든 데이터 전송 가능
단순함, 확장 가능
- HTTP는 단순하다. 스펙도 읽어볼만...
- HTTP 메시지도 매우 단순
- 크게 성공하는 표준 기술은 이처럼 단순하지만 확장 가능한 기술
HTTP 정리
- HTTP 메시지에 모든 것을 전송
- HTTP 역사 HTTP/1.1을 기준으로 학습
- 클라이언트 서버 구조
- 무상태 프로토콜(stateless)
- HTTP 메시지
- 단순함, 확장 가능
- 지금은 HTTP 시대!
해당 글은 인프런에서 김영한님의 <모든 개발자를 위한 HTTP 웹 기본지식> 를 듣고 정리한 내용입니다.
https://www.zerocho.com/category/HTTP/post/5b344f3af94472001b17f2da
(HTTP) HTTP란 무엇인가 - 웹 개발자의 역할
안녕하세요. 이번 시간에는 HTTP에 대해서 알아보겠습니다. HTTP는 Hyper Text Transfer Protocol의 두문자어로, 인터넷에서 데이터를 주고받을 수 있는 프로토콜입니다. 프로토콜은 규칙이라고 생각하시
www.zerocho.com
https://tecoble.techcourse.co.kr/post/2021-10-12-scale-up-scale-out/
Scale-up과 Scale-out에 대해 알아보자!
…
tecoble.techcourse.co.kr
'WEB > HTTP 기본지식' 카테고리의 다른 글
7. HTTP 헤더1 - 일반헤더 (0) | 2023.08.20 |
---|---|
5. HTTP 메서드 활용 (0) | 2023.08.13 |
4. HTTP 메서드 (0) | 2023.08.10 |
2. URI와 웹 브라우저 요청 흐름 (0) | 2023.08.05 |
1. 인터넷 통신 (0) | 2023.08.04 |