모든 개발자를 위한 HTTP 웹 기본 지식 : HTTP

jkky98·2024년 7월 4일
0

HTTP

목록 보기
8/8

HTTP History

  1. HTTP/0.9 (1991년)

    • GET 메서드만 지원.
    • HTTP 헤더 미지원.
  2. HTTP/1.0 (1996년)

    • 메서드헤더 추가.
  3. HTTP/1.1 (1997년)

    • 가장 많이 사용되고, 중요한 버전.
    • 주요 RFC 변경 사항:
      • RFC2068 (1997년) → RFC2616 (1999년) → RFC7230~7235 (2014년).
  4. HTTP/2 (2015년)

    • 성능 개선 (멀티플렉싱을 통해 다중 요청/응답 동시 처리, 헤더 압축, 서버 푸시 등으로 지연 감소).
    • 여전히 TCP 기반.
  1. HTTP/3 (진행 중)
    • UDP 기반으로 변경하여 성능 개선.

최근 많은 대규모 웹사이트에서 HTTP/2HTTP/3을 도입하여 사용하고 있다. 그러나, HTTP/2HTTP/3HTTP/1.1의 성능을 개선한 버전이므로, HTTP 프로토콜을 학습할 때 가장 중요하게 알아야 할 것은 HTTP/1.1이다.

아래는 각각 GoogleNaver에서 사용 중인 프로토콜의 일부이다:

  • Google: HTTP/2, HTTP/3.
  • Naver: HTTP/2, HTTP/1.1.

이처럼 HTTP/2와 HTTP/3이 점차 확산되고 있지만, HTTP/1.1은 여전히 많은 시스템에서 사용되고 있는 핵심적인 버전이다.

클라이언트-서버 구조

클라이언트 (Client)

  • 클라이언트는 사용자의 요청을 생성하여 이를 서버로 전송하는 역할을 한다.
  • 일반적으로 웹 브라우저, 모바일 앱, 또는 HTTP 요청을 생성할 수 있는 애플리케이션이 클라이언트로 동작한다.
  • 클라이언트는 TCP/IP 소켓을 통해 서버와 연결을 설정하고, HTTP 요청 메시지를 서버로 전송한다.

서버 (Server)

  • 서버는 클라이언트의 요청을 수신 및 처리한 후, 응답을 클라이언트로 반환하는 역할을 한다.
  • 서버는 웹 서버 소프트웨어애플리케이션 서버를 포함할 수 있다.
  • 요청된 리소스를 제공하거나, 데이터베이스와 상호작용하여 동적인 콘텐츠를 생성할 수 있다.
  • 서버는 클라이언트로부터 받은 HTTP 요청 메시지를 처리하고, 이에 대한 HTTP 응답 메시지를 생성하여 TCP/IP 소켓을 통해 클라이언트로 전송한다.

Stateless 프로토콜

서버가 클라이언트의 상태를 보존하지 않는 통신 방식무상태(stateless)라고 한다. 무상태 통신은 서버가 클라이언트의 이전 요청 상태를 기억하지 않기 때문에, 확장성에서 큰 이점을 제공한다. 그러나 상태 관리가 필요한 경우에는 추가적인 구현이 필요하며, 클라이언트가 요청 시 더 많은 데이터를 전송해야 하는 단점이 있다.

Stateful과 Stateless 차이

Stateful 세계

Stateful한 환경에서는 서버가 클라이언트의 상태를 기억하며 요청 간에 상태 정보를 유지한다. 예를 들어:

  1. 고객: 이 스마트폰 얼마인가요?
    점원: 100만원입니다.
  2. 고객: 2개 구매하겠습니다.
    점원: 200만원입니다. 신용카드와 현금 중 어떤 결제 방식을 원하시나요? (스마트폰을 2개 구매한다는 상태를 기억 중)
  3. 고객: 신용카드로 구매하겠습니다.
    점원: 200만원 결제 완료되었습니다. (구매 상태와 개수를 계속 기억 중)

위의 대화는 인간 간의 소통 프로세스로, 점원이 클라이언트의 상태를 계속 기억하고 대화의 문맥을 유지한다.

그러나 Stateful 환경에서 서버가 다수일 경우, 아래와 같은 상황이 발생할 수 있다:

  1. 고객: 이 스마트폰 얼마인가요?
    점원A: 100만원입니다.
  2. 고객: 2개 구매하겠습니다.
    점원B: 200만원입니다. 신용카드와 현금 중 어떤 결제 방식을 원하시나요? (점원B는 점원A로부터 상태를 받아야 함)
  3. 고객: 신용카드로 구매하겠습니다.
    점원C: 200만원 결제 완료되었습니다. (점원C는 B로부터 상태를 받아야 함)

이 과정에서, 만약 점원B가 "?? 무엇을 두 개 구매한다는 거죠?"라고 물어본다면, 이는 고객의 요청 상태를 유지하지 못한 것으로, Stateful 환경에서는 불완전한 처리로 간주된다.

Stateless 세계

  1. 고객: 이 스마트폰 얼마인가요?
    점원: 100만원입니다.
  2. 고객: 스마트폰 2개 구매하겠습니다.
    점원: 스마트폰 2개는 200만원입니다. 신용카드와 현금 중 어떤 결제 방식을 원하시나요?
  3. 고객: 스마트폰 2개를 신용카드로 구매하겠습니다.
    점원: 200만원 결제 완료되었습니다.

Stateless 세계에서는 위와 같이 질문마다 모든 정보를 포함해 요청해야 한다. 실제 현실에서는 점원이 5초 전 질문의 문맥을 기억하므로 Stateful한 소통이 자연스럽지만, Stateless 방식도 목표를 이루는 데는 문제가 없다. 다만, 소통 방식이 어색하게 느껴질 뿐이다.

Stateless의 특징은 요청이 독립적이라는 점이다. 따라서, 중간에 다른 점원(서버)으로 바뀌어도 요청 처리에 문제가 없다. 위의 비유에서 StatefulStateless의 차이는 질의자가 어떤 가정을 하느냐에 달려 있다:

  • Stateful: 상대방이 내 이전 질의를 기억할 것이라 가정.
  • Stateless: 상대방이 내 이전 질문 정보를 모른다고 가정하고 질의.

결과적으로, Stateless 방식은 요청마다 필요한 모든 정보를 포함하므로 서버 간 독립성이 보장되며, 확장성과 유연성을 제공한다.

확장성

이러한 무상태(Stateless)의 이점을 이해했다면, 클라이언트는 수신자가 자신의 상태 정보를 보관하지 않을 것을 전제로 요청을 보낸다. 이로 인해, 서버를 무한히 증설하는 것이 가능해진다.

예를 들어, ClientA서버1과 통신 중일 때 서버1에서 에러가 발생한다면, Stateful 통신에서는 서버1이 보유하고 있던 ClientA의 상태 정보를 다른 서버로 전달해야 한다. 이는 서버 간 동기화 부담을 초래하며 확장성을 제한한다.

반면, Stateless 통신에서는 중개 서버(로드 밸런서)가 ClientA의 요청을 단순히 다른 서버로 옮겨주기만 하면 된다.
클라이언트가 요청마다 필요한 상태 정보를 포함하고 있으므로, 새로운 서버에서도 요청을 문제없이 처리할 수 있다. 이로 인해 서버 증설에 대한 부담이 최소화된다(물론 서버를 늘리는 자체 비용은 제외).

결과적으로, 무상태 통신은 확장성유연성에서 큰 이점을 제공한다.

Stateless 실무 한계

Stateless의 이점이 많지만, 상태 유지가 반드시 필요한 경우도 있다. 대표적인 예가 로그인 상태 유지이다.
이를 위해 브라우저 쿠키서버 세션 등을 활용하여 상태를 유지한다.

그러나 Stateless의 장점을 유지하기 위해, 상태 유지가 필요한 경우에도 최소한의 상태 유지 기능만 사용하는 것이 중요하다. 예를 들어, 서버에서 모든 상태를 기억하는 대신 토큰 기반 인증(JWT)을 활용하거나, 상태 정보를 클라이언트에 저장해 서버의 부담을 줄이는 방식이 선호된다.

비연결성 (Connectionless)

HTTP의 비연결성IP의 비연결 지향성과 약간 다르다.
IP는 기본적으로 비 연결 지향적이지만, TCP의 3-way handshake를 통해 논리적 연결을 형성한다.


비연결성의 필요성

만약 여러 클라이언트가 서버와의 첫 통신 이후에도 계속 연결을 유지한다면, 서버의 자원이 지속적으로 소모된다.
서버는 연결을 유지하기 위해 객체를 생성하며, 이는 CPU와 메모리 자원을 점유한다.

이를 방지하기 위해 HTTP는 요청-응답이 끝난 후 TCP/IP 연결을 해제한다.
즉, 클라이언트가 다시 서버와 통신하려면 3-way handshake 과정을 반복해야 한다.


비연결성의 장점과 단점

  • 장점: 서버는 불필요한 연결을 유지하지 않아 최소한의 자원만 사용한다.
  • 단점: 매번 통신 시 3-way handshake를 새로 수행하므로, 연결 유지 방식에 비해 시간 비용이 증가한다.

결론적으로, HTTP의 비연결성은 서버 자원의 효율적 사용을 위해 설계된 방식이지만, 연결 성립에 따른 시간 비용 증가라는 트레이드오프를 감수해야 한다.

시간 비용에 대한 한계 극복

TCP/IP 연결을 새로 맺기 위해서는 3-way handshake 과정이 필요하므로, 요청마다 연결을 반복적으로 설정하는 방식은 연결 유지 방식에 비해 시간 비용이 발생한다.

이를 해결하기 위해 HTTP Persistent Connections(HTTP 지속 연결)이 도입되었다.
HTTP/1.1부터 기본으로 지원되며, 하나의 TCP 연결을 여러 요청과 응답에 재사용하여 연결 비용을 줄이고 성능을 향상시킨다.


지속 연결의 동작 방식

  1. Connection 헤더

    • HTTP 요청과 응답의 헤더에 Connection: keep-alive를 명시하여 연결을 유지한다.
    • 기본적으로 HTTP/1.1에서는 지속 연결이 활성화되어 있어, 별도의 설정 없이도 동작한다.
  2. 여러 요청 처리

    • 클라이언트는 동일한 TCP 연결을 사용하여 여러 개의 요청을 순차적으로 전송한다.
    • 서버는 각 요청에 대한 응답을 순서대로 반환한다.
  3. 연결 종료

    • Connection: close 헤더를 명시하거나, 일정 시간이 지나도록 추가 요청이 없을 경우 서버가 연결을 종료한다.
    • 이 시간은 타임아웃 값으로 조정 가능하다.

HTTP/2HTTP/3에서는 이러한 지속 연결 방식이 더욱 최적화되었으며, 멀티플렉싱과 같은 기술로 여러 요청을 동시에 처리하여 지연 시간을 대폭 감소시켰다.

실무에서 지속연결

HTTP 지속 연결시간 비용을 줄이는 장점이 있지만, 서버 자원 비용을 증가시키는 단점이 있다. 즉, Trade-off가 존재한다. 연결을 유지하려면 서버는 클라이언트당 메모리, CPU, 소켓 등의 자원을 지속적으로 할당해야 하므로, 요청 수가 폭증하는 상황에서는 서버 자원 부족 문제가 발생할 수 있다.


Connectionless 방식의 효율성

실제 대부분의 보통 환경에서는 요청량이 적거나 간헐적인 클라이언트 요청에 대해, Connectionless 방식이 서버 자원을 효율적으로 사용하는 경우가 많다. 연결을 종료하고 필요할 때 다시 연결을 설정하므로, 유휴 연결로 인한 자원 낭비를 방지할 수 있다.


큰 어플리케이션의 사례

  • Google 검색(지속 연결):
    Google은 HTTP 지속 연결을 사용하지만, 워낙 요청량이 많기 때문에 로드 밸런싱커넥션 풀링 기술을 함께 활용하여 효율성을 극대화한다. 이러한 구조로도 서버 자원 부담이 커지는 경우가 많아, 필요에 따라 연결을 종료하거나 다른 서버로 요청을 분산시킨다.

  • RESTful API(비연결성):
    대부분의 REST API 설계에서는 Connectionless 방식을 기본으로 채택한다. 요청이 독립적으로 처리되며, 응답 후 연결이 종료되므로 서버 자원 사용량이 낮다. 상태 정보를 유지하지 않으므로 확장성이 높은 설계가 가능하다.

  • 대형 스트리밍 서비스(Netflix, YouTube)(지속연결):
    이와 같은 서비스는 HTTP 지속 연결을 적극 활용한다. 지속적인 데이터 스트리밍이 필요하기 때문에, 연결을 유지하면서 데이터를 효율적으로 전송한다. 이 경우에도 서버 자원 문제를 최소화하기 위해 QUIC(HTTP/3)를 도입하여 전송 효율을 높이고 연결 설정 비용을 줄인다.


결론

HTTP 지속 연결Connectionless 방식은 각각의 장단점이 있으므로, 사용 환경과 애플리케이션의 특성에 따라 선택하는 것이 중요하다. 요청이 독립적이고 간헐적인 경우 Connectionless 방식이 적합하며, 실시간 스트리밍처럼 지속적인 데이터 전송이 필요한 경우 지속 연결 방식이 적합하다.

profile
자바집사의 거북이 수련법

0개의 댓글