HTTP는 뭘까
웹 통신에서 매번 빼놓지 않고 보이는 HTTP는 꽤나 중요해보인다.
웹 서핑할때 주소 앞에 http를 적었던 게 기억나기도 하고, 모든 웹 주소마다 들어가는걸 보면 호기심이 생겨나기도 한다.
이 녀석이 뭔지 알아보자.
HTTP
HyperText Transfer Protocol
HTTP는 HyperText Transfer Protocol이다. 그러니까 HyperText 문서를 통해서 통신할 수 있는 프로토콜이다. 처음엔 HyperText 통신에서 시작했지만 지금에 와서는 이미지, 영상, 음성, 파일 그리고 JSON, XML을 포함하는 모든 형태의 데이터를 다 통신한다.
그만큼 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. 기반 프로토콜
- TCP: HTTP/1.1, HTTP/2
- UDP: HTTP/3
TCP의 3-way handshake 없이 UDP 프로토콜 위에 애플리케이션 레벨에서 성능이 최적화되도록 설계된게 3버전이다.
2와 3버전도 현재 빠르게 퍼져나가고 있다.
2. 클라이언트 서버 구조
HTTP는 클라이언트가 HTTP 메세지로 서버에 요청을 보내고, 서버에서 응답 HTTP 메세지를 받는 클라이언트 서버 구조로 되어있다.
여기에서 집중해야 하는 점은 클라이언트와 서버를 개념적으로 분리함으로써 클라이언트는 편리하게 사용만 하게 하는 것에 있다.
이렇게만 이야기하면 다소 추상적으로 느껴질 수가 있다. 일상에서 클라이언트와 서버 구조와 닮은 예시를 살펴보자.
차가 고장났을 때 운전자(클라이언트)는 카센터(서버)에 가서 차를 맞기면, 카센터에서 운전자가 요청한 차 수리에 필요한 작업(비즈니스 로직, 데이터 처리)을 하고 운전자에게 차를 돌려준다. 운전자는 차를 카센터에 가져가서 수리를 요청하기만 할 줄 알면 되는 것이다.
3. Stateless Protocol을 지향
HTTP는 Stateless Protocol을 지향한다. 이 프로토콜을 쉽게 이해하기 위해서 우리의 일상에 맞춰서 한 번 개념을 들여다 본 후, 실제 상황을 설명하겠다.
3-1. 일상에 맞춰 프로토콜을 이해해보기
Stateless Protocol은 서버에서 클라이언트와 통신한 문맥을 기록해두지 않는다는 전제 하에 통신하는 방식이다. 그리고 Stateful Protocol은 반대로 기록해둔다는 전제 하에 통신하는 방식이다.
만약 우리가 서브웨이에 가서 샌드위치 결제를 하려고 할 때, 캐셔가 결제를 위해 질문을 두 번 하는데
질문을 한 번 하고, 답변을 듣고 나면 그때마다 주방에 급한 일이 생겨서 다른 캐셔 분으로 바뀐다고 해보자.
Stateful Protocol로 우리가 소통한다면, 이런 식이 될 것이다.
1
2
3
4
5
6
7
캐셔 1: 세트와 단품, 둘 중 어느 걸로 하실까요?
나: 단품이요.
캐셔 2(바뀜): 드시고 가실까요, 가져가실까요?
나: (이전 질문에 답변한 건 전달받으셨겠지?) 먹고 갈게요.
캐셔 2: (세트와 단품을 뭘로 해야할지는 모른다.)
Stateless Protocol로 우리가 소통한다면, 이렇게 할 것이다.
1
2
3
4
5
6
7
캐셔 1: 세트와 단품, 둘 중 어느 걸로 하실까요?
나: 단품이요.
캐셔 2(바뀜): 드시고 가실까요, 가져가실까요?
나: (전에 답변한 내용을 모르실 수 있겠다.) 샌드위치 단품으로, 먹고 갈게요.
캐셔 2: (굿!)
두 프로토콜에 어떤 차이가 있는지 더 정확히 알아보자.
3-2. 더 정확히 알아보자
3-1.에서 설명한 내용은 이해하기는 좋지만 정확한 설명은 아니다.
정확하게는 ‘서버가 클라이언트의 상태를 보존하지 않는’ 통신 방식이 Stateless Protocol이다.
Stateful은 ‘서버가 클라이언트의 상태를 보존하는 방식’ 이니까 클라이언트는 서버가 기억하고 있을 것이라고 생각하고 답변한다.
그런데 클라이언트 서버 구조에서 클라이언트는 서버가 어떻게 작동되는지는 모르고 Protocol에 맞춰 사용할 뿐이다.
그렇기 때문에 서버가 바뀌어도 클라이언트는 모른다.
1
2
3
4
5
6
7
캐셔 1: 세트와 단품, 둘 중 어느 걸로 하실까요?
나: 단품이요.
캐셔 2(바뀜): 드시고 가실까요, 가져가실까요?
나: (캐셔 분이 바뀐지 모른다, 전에 대답한 내용을 알고 있겠지) 먹고 갈게요.
캐셔 2: (세트와 단품을 뭘로 해야할지는 모른다.)
그리고 Stateless는
1
2
3
4
5
6
7
캐셔 1: 세트와 단품, 둘 중 어느 걸로 하실까요?
나: 단품이요.
캐셔 2(바뀜): 드시고 가실까요, 가져가실까요?
나: (캐셔 분이 바뀐지 모른다, 근데 이전 질문에 대한 답변에 덧붙여 대답하기로 했다.) 샌드위치 단품으로, 먹고 갈게요.
캐셔 2: (굿!)
매번 이렇게 대답을 길게 해야 한다니, 내가 일상에서 이렇게 지내야 한다면 굉장히 불편할 것만 같다.
HTTP는 왜 이런 Stateless Protocol을 지향하는 걸까?
그 이유를 이해하기 위해서는 서버 운영 측면에서 바라볼 필요가 있다.
서버는 때때로 급작스럽게 많은 클라이언트 요청들을 받을 수도 있다. 콘서트 예매 사이트의 서버나 수강신청 서버가 그런 상황에 놓이곤 한다. 그러한 유동적인 트래픽을 처리하기 위해서는 서버 또한 유동적으로 스케일 인, 스케일 아웃 할 수 있어야 한다. 만약 통신 중이던 서버에 장애가 생긴다면 다른 서버가 대신 일해야 하는데, Stateful이라면 처음부터 다시 요청을 해야한다. Stateless는 데이터를 모두 담아서 보내기 때문에 쉽게 응답 서버를 바꿀 수 있다.
그게 바로 HTTP가 이 프로토콜을 지향하는 이유다.
4. Stateless의 한계
운영하는 입장에서 Stateless Protocol이 완벽하지는 않다.
첫 번째는 전송해야 하는 데이터량이 너무 커서 생기는 한계가 있고,
두 번째는 한계는 모든 걸 무상태로 설계할 수는 없다는 점이 있다. 예를 들어 우리가 로그인해서 메일을 확인하려면, 서버가 로그인 상태를 유지해야 하기 때문이다. 그래서 필요할 때는 쿠키와 세션을 조합해서 상태를 유지하는 방법을 사용한다.
그런 상태 유지도 최소한으로 사용해야 한다.
5. 비 연결성
HTTP는 연결을 유지하지 않는 모델이다. 그렇기 때문에 서버 자원을 매우 효율적으로 사용할 수 있다. 실제로 요청과 응답을 주고 받을 때만 연결을 유지하며 주고받는게 끝나면 TCP/IP 연결을 끊는다.
HTTP는 일반적으로 초 단위 이하의 빠른 속도로 응답하기 때문에 1시간 동안 수만명이 사용해도 동시에 처리하는 요청은 수십개 이하로 매우 적다.
이런 장점은 트래픽이 많지 않고, 빠른 응답을 제공할 수 있는 상황이 계속된다면 장점이 되지만
트래픽이 많고, 큰 규모의 서비스를 운영할 때는 한계가 있다.
참고!
TCP/IP는 기본적으로 연결을 유지하는 연결성 모델이다. 클라이언트의 요청이 없어도 연결을 유지해서 서버 자원이 낭비되어진다.
6. HTTP 지속 연결 (Persistent Connections)
하나의 웹 페이지를 만들기 위해서는 HTML을 포함한 자바스크립트, CSS, 이미지 등의 많은 리소스를 받아와야 한다.
그런데 HTTP는 비연결성 모델이기 때문에 해당 자원들을 각각 받을 때마다 연결을 끊고 연결을 다시 하고를 반복해야 한다. 비연결성 모델이 갖는 한계가 바로 이것인데, 이걸 보완하기 위해 HTTP Persistence Connections이 등장한다.
이 연결 방식은 하나의 웹 페이지 리소스를 모두 내려받기 전까지 연결을 유지한다. 그렇기 때문에 비 연결성 모델의 장점은 가져가면서 한계를 해결할 수 있다.