HTTP의 역사

이종현·2023년 3월 20일
0

HTTP

목록 보기
1/3
post-thumbnail

1. HTTP의 버전별 등장시기

년도1991년1996년1997년2015년진행중
HTTP 버전HTTP/0.9HTTP/1.0HTTP/1.1HTTP/2.0HTTP/3.0
HTML 버전HTML 1.0HTML 2.0(1995년)
웹페이지수(추정)약 5만개약 150만개3억개 (1999년)17억개

이 글의 제목을 HTTP의 역사라고 정했어도 주로 버전에 대해서 이야기할 것 같습니다. 버전이 발전해온 과정 그 자체가 역사니까, 하지만 HTTP가 버전별로 등장한 시기가 웹이 발전한 과정,즉 웹의 역사에서 어떻게 발전했는지에 대해 나름 정리해보고 개인적인 의견도 이 글에 남겨봅니다.

1.1 월드와이드웹의 등장 (HTTP/0.9)

출발은 월드와이드웹 입니다. 팀버너스리가 인터넷을 기반으로 한 정보 공유 시스템을 만들었는데, 그게 바로 월드 와이드 웹 입니다. 이때 문서를 전송할 수 있는 프로토콜을 개발했는데, 이것이 HTTP입니다. 이때의 초기버전을 HTTP/0.9 라고 부릅니다.

1.2 1차 웹 브라우저 전쟁 이후 (HTTP/1.0)

이후 HTTP/1.0 버전이 1996년에 등장하기 전에 넷스케이프사와 마이크로소프트사의 1차 웹브라우저 전쟁이 1995년도에 있었습니다. 이런 경쟁들로 보통 기술들은 빠르게 성장하게 됩니다. 비록 이 시대의 개발자들은 여러 브라우저에 맞는 요구사항을 모두 맞춰서 개발해야 하는 크로스브라우징 이슈 때문에 엄청 고생했던 것으로 알고 있습니다. 하지만 이후 HTTP/1.0과 HTML 2.0의 등장으로, 웹페이지를 효율적으로 구성할 수 있는 기술적인 개선이 이루어졌습니다. 이때부터 개발자들이 좀 더 효율적으로 개발할 수 있었을 거라 생각합니다.

HTTP/1.0은 초기 버전의 HTTP 프로토콜로써, 이전에 사용되던 Gopher와 같은 다른 프로토콜에 비해 훨씬 효율적인 웹통신을 가능하게 했습니다. HTTP/1.0은 지속적인 연결을 통한 요청과 응답 처리, 캐싱과 프락시 서버의 지원 등을 추가했기 때문에, 웹페이지의 로딩 속도를 향상시키는 데 큰 역할을 했습니다.

HTML 2.0은 초기 버전의 HTML로써, 이전 버전에 비해 많은 기능을 추가하여 웹페이지를 보다 효율적으로 구성할 수 있도록 했습니다. 예를 들어, FORM 태그와 이미지 맵, 표 등의 기능을 추가하여, 사용자와의 상호작용과 정보 전달을 더욱 효율적으로 할 수 있었습니다.

따라서, HTTP/1.0과 HTML 2.0의 등장으로 인해 웹페이지의 효율성이 향상되었고, 이후에도 지속적인 기술적인 발전이 이루어져 현재의 웹페이지는 더욱 높은 수준의 효율성과 사용성을 제공할 수 있게 되었습니다.

1.3 HTML의 발전과 CSS의 등장 그리고 JavaScript의 등장 (HTTP/1.1)

HTTP/1.1은 HTTP/1.0이 등장하고 얼마 지나지 않아 공식적으로 RFC 2068에 정의되었고 계속 업데이트를 통해 RFC 2616에 여러 개선점이 최종적으로 편입되었습니다.

KeepAlive, 가상호스팅, 파이프라인, 캐시제어, Range Requests, OPTIONS 메서드, Host헤더 필드, 커넥션 관리, Transfer-Encoding, chunked response 등 HTTP/1.1의 이런 다양한 개선 사향들은 웹의 다양한 부분에서 발전을 이루게 되었습니다. 이러한 발전으로 인해 웹은 보다 빠르고 효율적이며, 보안성과 신뢰성도 향상되었습니다. 또한 이 시기에 즈음에는 HTML도 3.2 버전을 통해 표준화 작업을 진행하고 CSS와 JavaScript(ES1)도 등장하게 됩니다.

이후 CSS와 JavaScript는 계속 발전을 거듭해나갔지만, HTTP/1.1의 경우는 ES6가 등장하기 전까지 15년 동안이나 유지됩니다.

1.4 ES6의 등장 (HTTP/2.0)

HTTP/2.0과 ES6가 같은 해인 2015년에 등장했지만, 이 두 기술은 직접적인 관련성은 없습니다. 하지만 두 기술은 웹 개발에 있어 현재도 중요한 기술로 자리 매김하고 있습니다.

HTTP/2.0은 웹 프로토콜을 개선하여 웹의 성능을 향상시키는 목적으로 개발되었고, ES6는 JavaScript 언어의 새로운 기능을 도입하여 개발자가 보다 쉽고 간결하게 코드를 작성할 수 있도록 하는 것이 목적입니다.

하지만 HTTP/2.0과 ES6는 모두 웹 애플리케이션의 개발과 성능 향상에 긍정적인 영향을 미쳤습니다. HTTP/2.0은 이전의 HTTP/1.1과 달리, 요청과 응답을 다중화하여 한 번의 연결로 여러 요청과 응답을 처리할 수 있게 되어 웹 페이지 로딩 속도를 향상시켰습니다. 이는 웹 개발자가 더욱 빠른 웹 페이지를 개발할 수 있도록 도와주었습니다.

ES6는 새로운 JavaScript 기능을 도입하여, 보다 간결하고 가독성이 높은 코드 작성을 가능하게 해주었습니다. 또한 모듈 시스템을 도입하여 코드의 재사용성을 높일 수 있게 되어, 웹 개발자가 보다 효율적인 개발을 할 수 있게 해주었습니다.

따라서 HTTP/2.0과 ES6은 각각 웹의 성능과 개발 생산성을 향상시켰으며, 웹 개발에 있어 중요한 기술로 자리 잡고 있습니다.

1.5 계속 발전하는 웹 (HTTP/3.0 )

ES6와 HTTP/2.0이 등장한 이후로 현재까지 웹은 지속적으로 발전해오고 있습니다.

2016년 이후 웹의 발전과정에는 다음과 같은 변화와 추세가 있었습니다.

  1. 웹 어셈블리: 2017년, Mozilla가 제안한 웹 어셈블리(WebAssembly)는 웹 브라우저 상에서 실행되는 고급 프로그래밍 언어로, C, C++, Rust 등의 언어를 사용하여 빠른 속도로 실행되는 웹 애플리케이션을 만들 수 있도록 해주었습니다.
  2. Progressive Web Apps: Progressive Web Apps(PWAs)는 모바일 기기에서 네이티브 앱과 같은 사용자 경험을 제공하는 웹 애플리케이션입니다. 2018년에는 Google이 PWA를 지원하는 Chrome 70 버전을 출시하여 PWA 개발을 쉽게 할 수 있도록 했습니다.
  3. 웹 컴포넌트: 웹 컴포넌트는 웹 애플리케이션을 구성하는 UI 컴포넌트를 재사용 가능한 형태로 만들어주는 기술입니다. 2019년, 웹 컴포넌트 표준인 Custom Elements, Shadow DOM, HTML Templates, HTML Imports가 W3C에서 공식적으로 표준화되었습니다.
  4. JavaScript의 발전: ECMAScript 2017(ES8)부터 2021년 현재의 ECMAScript 2022(ES13)까지 JavaScript 언어의 버전이 지속적으로 발전하면서, 비동기 프로그래밍, 모듈화, 화살표 함수, 클래스 등의 기능이 추가되었습니다.

HTTP/3.0은 2018년에 발표되었으며, 기존의 TCP 기반 연결 대신에 QUIC 프로토콜을 사용하여 데이터를 전송하는 새로운 웹 프로토콜입니다. QUIC은 UDP 기반의 프로토콜로, 이전의 TCP 기반 연결보다 더욱 빠르고 안정적인 연결을 제공합니다.

HTTP/3.0의 가장 큰 변화는 QUIC을 사용하게 됨으로써 더욱 빠르고 안정적인 연결을 제공한다는 것입니다. QUIC은 여러 가지 기술적인 개선 사항을 도입하여 웹 페이지 로딩 속도를 개선하고, 연결을 보다 안정적으로 유지할 수 있도록 해줍니다.

또한 HTTP/3.0은 HTTP/2.0과 달리 요청과 응답을 다중화하는 기능이 내장되어 있으므로, 더욱 빠르고 효율적인 데이터 전송이 가능해집니다.

각 버전별 특징에 대해서는 아래에서 좀 더 자세하게 알아보겠습니다.


2. HTTP 버전

2.1 HTTP/0.9

특징

  • 초기버전을 구분하기 위해 부르는 버전입니다.
  • 요청은 단일라인으로 구성되어 있고, 메서드는 GET만 존재합니다.
  • 응답은 단순하게 파일내용 자체로만 구성되어있습니다.
  • HTTP 헤더도 없이 html 파일만 전송했습니다. (다른 유형의 문서는 전송될 수 없음)
  • 상태코드도 없어서 문제가 있을 경우 파일 내부에 문제에 대한 설명을 함께 보내야 했습니다.
  • 단일 연결
    • TCP 연결을 매번 새로 맺고, 연결이 맺어지면 요청을 보내고 서버에서 응답을 받은 후에 연결을 끊었습니다. 이때 3-way handshake는 매번 요청마다 발생합니다.
<!-- 요청 -->
GET /mypage.html

<!-- 응답 -->
<html>
A very simple HTML page
</html>

처음에는 간단한 문서 정도를 주고 받는 용도로 만들었기 때문에 크게 복잡할 필요가 없었고 그래서 이렇게 단순하게 개발한 것이 아닐까 생각합니다. 제가 컴퓨터로 가장 처음 인터넷을 사용했을때가, 1999년도 즈음이었을 것 같은데.. (그때는 HTTP/0.9 버전은 아니였겠죠..;; 일부 HTTP/0.9 포트를 사용하는 사이트가 남아있었을지 모르지만 거의 없었다고 생각합니다. 주로 Yahoo를 이용했었는데..ㅋ;;) 그 당시에도 웹페이지는 엄청 단순했던 기억이 있는데 그래도 문서만 보여지거나 하는 정도는 아니였던 걸로 기억합니다.


2.2 HTTP/1.0

특징

  • 버전 정보, 상태코드 추가
  • 메세지에 헤더를 추가해서 메타데이터를 포함
  • CRLF 추가
  • POST, HEAD 메서드 추가

요청메세지

GET /file.html HTTP/1.0\r\n
Host: example.com\r\n
Connection: close\r\n
\r\n

응답메세지

HTTP/1.0 200 OK\r\n
Date: Fri, 18 Mar 2023 00:00:00 GMT\r\n
Content-Type: text/html\r\n
Content-Length: 1234\r\n
\r\n
<html><body>요청한 파일의 내용입니다.</body></html>

HTTP 버전 정보

HTTP/1.0의 요청과 응답입니다. 딱 봐도 HTTP/0.9보다는 메세지 안에 담겨있는 정보가 많아보입니다. 일단 버전 정보가 눈에 띄고요. 상태코드도 들어가 있습니다.
버전 정보는 HTTP 프로토콜의 버전을 나타내며, HTTP 클라이언트와 서버가 통신하는데 필요한 중요한 정보 중 하나입니다.

HTTP 프로토콜은 지속적으로 발전해왔기 때문에, 이전 버전과 호환되지 않는 새로운 기능이 추가될 수도 있습니다. 따라서 HTTP 메시지에서 버전 정보를 명시함으로써, 클라이언트와 서버가 현재 사용하고 있는 HTTP 버전이 무엇인지 알 수 있고, 서로 호환 가능한 기능들만 사용하여 통신할 수 있습니다.

또한, 버전 정보는 클라이언트와 서버가 통신하면서 문제가 발생했을 때 원인을 파악하는데 도움을 줍니다. 예를 들어, 클라이언트와 서버가 서로 다른 버전의 HTTP 프로토콜을 사용하고 있어서 생기는 문제를 해결할 때, 버전 정보를 확인하여 적절한 대응을 할 수 있습니다.따라서 HTTP 메시지에서 버전 정보는 매우 중요한 역할을 합니다.

상태 코드

또한 상태 코드 라인은 응답 메세지의 시작 부분에 붙어 전송되어 브라우저가 요청에 대한 성공과 실패를 알 수 있고 그에 대한 동작을 할 수 있게 되었습니다.

헤더 정보

위의 예제에서 Date, Content-Type, Content-Length 부분에 응답 메세지 헤더에 해당하는 요소 Host, Connection 부분 등이 요청 메세지 헤더에 해당하는 요소입니다.

HTTP 헤더는 메시지에 추가적인 메타데이터를 포함할 수 있는 구조로, 클라이언트와 서버 사이의 통신에 매우 중요한 역할을 합니다. HTTP 헤더가 메타데이터 전송을 허용함으로써, HTTP 메시지에 다양한 정보를 담을 수 있어서 유연하게 대응할 수 있습니다.

HTTP/1.0에서는 클라이언트와 서버 간에 컨텐츠 협상(content negotiation)을 위한 몇 가지 헤더 필드가 도입되었습니다. 이를 통해 클라이언트와 서버는 요청과 응답에서 사용할 수 있는 언어, 문자 인코딩, 미디어 타입 등의 컨텐츠 속성을 협상할 수 있습니다.

  1. Accept-Language 헤더
    클라이언트는 Accept-Language 헤더를 사용하여 선호하는 언어를 서버에게 전달합니다. 서버는 이를 바탕으로 요청된 자원의 언어를 선택할 수 있습니다.
  2. Accept-Charset 헤더
    클라이언트는 Accept-Charset 헤더를 사용하여 선호하는 문자 인코딩을 서버에게 전달합니다. 서버는 이를 바탕으로 응답 본문의 인코딩을 선택할 수 있습니다.
  3. Accept-Encoding 헤더
    클라이언트는 Accept-Encoding 헤더를 사용하여 선호하는 데이터 인코딩 방식(압축 방식)을 서버에게 전달합니다. 서버는 이를 바탕으로 응답 본문의 압축 방식을 선택할 수 있습니다.
  4. Content-Language 헤더
    서버는 Content-Language 헤더를 사용하여 응답 본문의 언어를 명시할 수 있습니다.
  5. Content-Type 헤더
    서버는 Content-Type 헤더를 사용하여 응답 본문의 미디어 타입을 명시할 수 있습니다. 클라이언트는 이를 바탕으로 응답 본문을 올바르게 해석할 수 있습니다.이는 다양한 종류의 파일을 전송하기 위해서입니다.
    이전에는 HTTP 0.9에서 HTML 파일만을 전송할 수 있었지만, HTTP 1.0에서는 Content-Type을 이용하여 HTML, 이미지, 오디오, 비디오 등 다양한 종류의 파일을 전송할 수 있게 되었습니다.예를 들어, HTML 파일은 text/html, 이미지 파일은 image/jpeg, 오디오 파일은 audio/mp3 등의 content-type을 갖습니다. 이렇게 content-type을 지정함으로써, 브라우저는 전송받은 파일을 적절한 방식으로 해석하고 표시할 수 있게 됩니다.따라서 content-type을 헤더에 추가함으로써, HTTP 1.0에서는 다양한 종류의 파일을 전송할 수 있게 되었습니다. 이전에는 브라우저가 전송받은 파일의 형식을 예측하여 해석했기 때문에, 이후 버전의 HTTP에서도 content-type을 중요한 요소로 취급하게 됩니다.

위와 같은 헤더들을 사용하여 컨텐츠 협상을 할 수 있으며, 이를 통해 클라이언트와 서버 간의 상호 운용성(interoperability)을 향상시킬 수 있습니다.

이외에도 클라이언트나 서버에서 정의한 사용자 지정 헤더를 추가하여, 필요한 정보를 전송할 수 있습니다. 이렇게 HTTP 헤더는 기본적으로 일부 정보를 제공하면서, 확장성 있는 구조로 설계되어 있기 때문에, 새로운 요구 사항이나 기능이 필요할 때 추가적인 헤더를 정의하여 사용할 수 있습니다.

따라서 HTTP 헤더 개념은 확장이 가능하다는 점에서 중요한 역할을 합니다. 이를 통해 HTTP 프로토콜은 지속적으로 발전하면서, 새로운 요구 사항과 기능을 지원할 수 있게 됩니다.

CRLF (Carriage Return Line Feed)

HTTP/0.9 버전에도 CRLF는 존재했지만 요청라인과 메시지 바디를 구분하고 메시지 바디의 끝을 나타내는 역할을 하는 등 요청 라인이 단일 라인이기 때문에 크게 눈에 띄지 않았습니다. 하지만 HTTP/1.0부터는 헤더 정보가 추가 되면서 CRLF가 조금 더 중요해집니다.

CRLF는 두 개의 ASCII 문자인 \r과 \n으로 이루어져 있으며, 각각 Carriage Return (CR)와 Line Feed (LF)의 조합을 의미합니다. 요청 라인, 상태 라인, 헤더와 메시지 바디 사이의 CRLF(공백 라인)은 헤더와 메시지 바디를 구분하기 위한 구분자입니다. 이 구분자는 헤더와 메시지 바디 사이에 하나 이상의 빈 줄을 생성합니다.

반면, 요청 라인과 상태 라인 맨 끝에 위치한 CRLF는 해당 라인의 끝을 알리는 역할을 합니다. 이 CRLF가 없으면 HTTP 메시지가 잘못된 형식으로 처리될 수 있습니다. 따라서 HTTP 프로토콜에서는 요청 라인과 상태 라인 맨 뒤에 CRLF를 반드시 붙여야 합니다. 두 CRLF가 헷갈릴 수 있지만 하나는 빈 줄을 생성하고 다른 하나는 메시지의 끝을 알리는 거라고 생각하면 좋을 것 같습니다.

예를 들어, 다음과 같은 요청 메시지가 있다고 가정해보겠습니다.

GET /index.html HTTP/1.1
Host: www.example.com

위의 요청 메시지에서 첫 줄인 요청 라인 뒤에는 CRLF가 추가되어야 합니다. 따라서, 실제로 전송되는 요청 메시지는 다음과 같이 됩니다.

GET /index.html HTTP/1.1\r\n
Host: www.example.com\r\n
\r\n

상태 라인과도 동일하게, 응답 메시지의 첫 줄인 상태 라인 뒤에도 CRLF가 추가됩니다. 예를 들어, 다음과 같은 응답 메시지가 있다고 가정해보겠습니다.

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234

위의 응답 메시지에서 첫 줄인 상태 라인 뒤에도 CRLF가 추가되어야 합니다. 따라서, 실제로 전송되는 응답 메시지는 다음과 같이 됩니다.

HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 1234\r\n
\r\n

새로운 메서드의 추가(POST, HEAD) 그리고 차이점

HTTP/1.0에서의 GET, HEAD, POST 메서드의 핵심적인 차이점은 다음과 같습니다.

  • GET: 서버로부터 리소스를 요청하고, 해당 리소스의 본문을 가져옵니다.
  • HEAD: GET과 동일한 방식으로 리소스를 요청하지만, 해당 리소스의 본문 대신에 헤더만을 가져옵니다.
  • POST: 서버로 데이터를 전송하고, 해당 데이터를 처리한 결과를 리턴받습니다.

즉, GET은 리소스를 가져오기 위해 사용되며, HEAD는 해당 리소스가 존재하는지 확인하거나, 헤더 정보만 필요한 경우에 사용됩니다. POST는 데이터를 서버로 전송하고, 해당 데이터를 처리한 결과를 받는 데 사용됩니다.


2.3 HTTP/1.1

2.3.1 특징

  • 오늘날 가장 많이 사용하는 버전 (그런데 내가 자주 가는 사이트(ChatGPT,구글, 네이버, 쿠팡, 블로그, 등은 HTTP/2.0 프로토콜이 더 많았습니다. 그런데 HTTP/1.1이 등장하고부터 HTTP/2.0 이 등장하는 시기 사이는 15년 이라는 시간이 존재합니다. 아마 전 세계에 있는 웹사이트를 기준으로 봤을 때 가장 많이 사용되는 HTTP 버전을 이야기하는 것이 아닌가 생각해 볼 수 있습니다.)
  • 영구 및 파이프 라인 연결
  • 압축/압축 해제
  • 가상 호스팅
  • Upgrade로 WebSocket 전환 가능
  • 청크 전송 인코딩(Chunked Transfer Encoding)
  • Method: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS
  • 캐시

Keep Alive(지속적인 연결)

HTTP/1.1에서는 이전 버전과는 달리, TCP 연결을 하나 맺은 후에 여러 요청과 응답을 처리할 수 있게 되었습니다. 이때 3-way handshake는 연결을 맺을 때 한 번만 발생하며, 연결이 끊어질 때만 다시 발생합니다. 이러한 지속적인 연결을 사용하면, 매번 TCP 연결을 맺고 끊는 데 필요한 시간과 자원이 절약되어 웹 페이지의 로딩 속도가 빨라집니다.

지속적인 연결을 사용하는 예시

GET /page1.html HTTP/1.1
Host: www.example.com
Connection: keep-alive

GET /page2.html HTTP/1.1
Host: www.example.com
Connection: keep-alive

PipeLine

파이프라이닝(pipelining)은 HTTP/1.1에서 지원하는 기능으로, 클라이언트가 서버로 여러 개의 요청을 한꺼번에 보내고, 서버가 응답을 한꺼번에 보내는 것을 말합니다. (하나의 파이프안에다가 담아서 한 번에 보낸다고 이해하면 쉽지 않을까요?) 이를 통해 불필요한 대기 시간을 줄여 전송 속도를 향상시킬 수 있습니다.

그러나 파이프라이닝은 모든 요청과 응답이 순차적으로 처리되지 않고, 병렬로 처리되기 때문에 하나의 요청이 지연되면 이후 요청에 대한 응답도 함께 지연됩니다. 이렇게 지연되는 시간을 레이턴시(latency)라고 합니다.

레이턴시는 네트워크 상황, 서버의 처리 속도 등에 따라 다양한 요인에 의해 영향을 받습니다. 파이프라이닝을 사용할 때는 레이턴시를 최소화하기 위해 서버의 응답 시간이 길어지는 요청을 최대한 배제하고, 요청 간의 우선순위를 고려하여 보내는 것이 중요합니다.

또한 하나의 커넥션에 여러개의 요청이 들어있을 뿐, 여러개의 요청을 동시에 처리해 응답으로 보내주는 것이 아닙니다. (multiplexing 되지는 않는다.)

  • HTTP 1.1: 하나의 TCP Connection이 열려있으면 (Established 상태), 그 연결을 통해 여러 Request에 대한 Response를 받을 수 있다.
  • HTTP 1.1 Keep-Alive Pipelining: Pipelining을 사용할 때, client는 여러 request를 response의 응답을 기다리지 않고 보낼 수 있다.

파이프라인 연결을 사용하는 예시

GET /page1.html HTTP/1.1
Host: www.example.com

GET /page2.html HTTP/1.1
Host: www.example.com

Keep Alive와 PipeLine이 헷갈릴 수 있어 다시 한 번 정리해보겠습니다.

하나의 TCP 연결을 통해 여러 개의 Request-Response를 처리할 수 있습니다. 이를 통해, 연결을 재사용함으로써 TCP 연결을 매번 새로 만들 필요가 없어져 시간과 자원을 절약할 수 있습니다. 이를 keep-alive 연결이라고 합니다.

파이프라인(Pipelining)은 클라이언트가 여러 개의 Request를 한 번에 서버로 보내고, 서버는 이에 대해 여러 개의 Response를 한 번에 클라이언트로 보내는 기술입니다. 파이프라이닝을 사용하면, 한 번에 여러 개의 요청을 보내므로 Keep Alive를 사용하는 것보다 더 빠른 성능을 보장할 수 있습니다.

하지만 파이프라인은 클라이언트와 서버 간의 동기화 문제가 발생할 수 있습니다. 클라이언트는 서버로부터 이전 요청의 응답을 받은 후에 다음 요청을 보내야 하지만, 파이프라인을 사용하면 여러 개의 요청을 한 번에 보내므로 이전 요청의 응답을 받지 않았더라도 다음 요청을 보내게 됩니다. 이러한 문제를 해결하기 위해서는 클라이언트와 서버가 적절한 동기화 방식을 사용해야 합니다.

따라서 keep-alive 연결과 파이프라인은 모두 여러 개의 Request-Response를 처리하는 방법이지만, keep-alive 연결은 동시에 처리하지 않고 연속적으로 처리하며, 파이프라인은 동시에 처리하려고 시도합니다.

압축/ 압축 해제

HTTP/1.1은 메시지를 전송할 때 압축 기술을 사용할 수 있습니다. 이는 전송 데이터양을 줄이고, 대역폭을 절약하며, 응답속도를 향상시키는 효과가 있습니다.

HTTP/1.1은 gzip 압축을 지원합니다.

Accept-Encoding: gzip

가상호스팅

가상호스팅(virtual hosting)은 하나의 서버에서 여러 개의 도메인을 호스팅하는 방법입니다. 이를 통해 하나의 서버에서 여러 개의 웹사이트를 운영할 수 있습니다.

HTTP/1.1에서 가상호스팅은 "Host"라는 헤더 필드를 이용하여 구현됩니다. 브라우저가 서버에 요청을 보낼 때, 요청 메시지에는 "Host" 필드에 요청하는 도메인 이름이 포함됩니다. 서버는 이 정보를 바탕으로 요청한 도메인에 대응하는 가상 호스트를 찾아서 처리합니다.

가상호스팅을 구현하는 방법에는 두 가지가 있습니다. 첫 번째 방법은 IP 기반 가상호스팅입니다. 이 방법은 서버에 할당된 IP 주소를 이용하여 요청한 도메인에 대응하는 가상호스트를 찾습니다. 두 번째 방법은 이름 기반 가상호스팅입니다. 이 방법은 "Host" 필드에 요청한 도메인 이름을 이용하여 가상호스트를 찾습니다.

이러한 가상호스팅 방법을 이용하여 하나의 서버에서 여러 개의 웹사이트를 운영할 수 있으며, 각각의 도메인은 서로 독립적인 공간을 가지게 됩니다. 이를 통해 서버의 자원을 효율적으로 사용할 수 있습니다.

Web Socket

HTTP/1.1은 기본적으로 클라이언트와 서버 간에 단방향 통신을 하는 방식입니다. 이러한 HTTP의 한계를 극복하기 위해 Web Socket이라는 기술이 등장했습니다. Web Socket은 양방향 통신을 가능하게 하는 기술로, 실시간 웹 애플리케이션을 구현할 때 매우 유용합니다.

Web Socket은 HTTP와 마찬가지로 TCP/IP 프로토콜을 기반으로 동작합니다. 그러나 일반적인 HTTP 통신과는 달리, 클라이언트와 서버 간에 전이중(full-duplex) 통신을 가능하게 합니다. 전이중 통신이란 클라이언트와 서버가 동시에 데이터를 보낼 수 있는 것을 의미합니다. 이를 통해 클라이언트와 서버 간에 실시간으로 데이터를 주고받을 수 있습니다.

Web Socket은 HTTP Upgrade와 Handshake라는 과정을 통해 클라이언트와 서버 간의 Web Socket 연결을 수립합니다. 이후에는 클라이언트와 서버가 데이터를 주고받을 수 있습니다.

Web Socket을 이용하면 실시간으로 데이터를 주고받는 채팅 애플리케이션, 주식 시세 등의 실시간 정보 제공 서비스, 게임 등에 활용할 수 있습니다. 또한 Web Socket은 HTTP/1.1과 호환성이 좋으며, 대부분의 최신 웹 브라우저에서 지원됩니다.

청크 전송 인코딩(Chunked Transfer Encoding)

"청크(chunk)"란 큰 데이터를 작은 조각으로 나누어 전송하는 것을 말합니다. 따라서 "청크된 응답(chunked response)"은 응답 데이터가 작은 조각으로 나뉘어 전송되는 것을 의미합니다. 이렇게 하면 브라우저가 데이터를 일부분만 받아도 렌더링을 시작할 수 있기 때문에 전체 데이터를 받기까지 기다리지 않아도 되어 페이지 로딩 속도가 향상됩니다.또한 전체 데이터의 크기를 미리 알 필요가 없어지므로, 대용량 파일 전송 등에서 유용하게 사용됩니다.

청크 전송 인코딩은 다음과 같은 상황에서 사용됩니다.

  1. 서버가 데이터의 크기를 미리 알 수 없는 경우
  2. 클라이언트가 서버로부터 일부 데이터만 수신하고 싶은 경우
  3. 서버가 데이터를 일부씩 전송하여, 실시간으로 처리해야 하는 경우

청크 전송 인코딩은 일반적으로 Transfer-Encoding 헤더 필드를 사용하여 표시됩니다. 이 헤더 필드의 값은 "chunked"로 설정됩니다. 각 청크의 크기는 16진수로 표시된 값을 헤더에 포함하며, 모든 데이터가 전송된 후에는 0으로 표시된 청크가 전송됩니다.

따라서, 청크 전송 인코딩은 HTTP/1.1에서 데이터 전송을 보다 유연하고 효율적으로 처리할 수 있도록 지원되는 기술입니다.

메서드의 추가(OPTIONS, PUT, DELETE, TRACE)

HTTP/1.1에서 추가된 OPTIONS, PUT, DELETE, TRACE 메서드는 이전 버전의 HTTP 메서드와는 다른 목적과 기능을 가지고 있습니다.

OPTIONS 메서드는 서버에게 요청 가능한 메서드들의 목록을 요청합니다. 이를 통해 클라이언트는 서버가 지원하는 메서드를 파악하고, 요청을 보낼 때 적절한 메서드를 선택할 수 있습니다.

PUT 메서드는 서버에게 리소스를 생성 또는 갱신하도록 요청합니다. 클라이언트는 PUT 메서드를 이용하여 서버에게 리소스를 전송하고, 서버는 해당 리소스를 생성하거나 갱신합니다.

DELETE 메서드는 서버에게 리소스를 삭제하도록 요청합니다. 클라이언트는 DELETE 메서드를 이용하여 서버에게 리소스 삭제를 요청하고, 서버는 해당 리소스를 삭제합니다.

TRACE 메서드는 클라이언트가 보낸 요청 메시지를 그대로 반환하는 기능을 가지고 있습니다. 이를 통해 클라이언트는 서버와의 통신 과정에서 요청 메시지가 어떻게 변경되었는지를 추적할 수 있습니다.

이러한 메서드들은 기존의 HTTP 메서드들과는 다른 목적과 기능을 가지고 있지만, 이전 버전의 HTTP 메서드들이 웹 데이터의 증가로 인해 부족한 점을 보완하기 위해서도 추가되었습니다. 이전 버전의 HTTP 메서드들은 주로 정적인 컨텐츠를 가져오는 데에만 초점을 두고 있었지만, 웹 데이터가 다양해지면서 동적인 데이터를 생성하고 갱신하는 기능이 필요해졌기 때문입니다. 또한, REST 아키텍처를 따르는 웹 서비스에서는 이러한 메서드들이 필요한 경우가 많습니다.

캐시(cache)

HTTP/1.1은 웹 페이지의 성능을 향상시키기 위한 여러 가지 기능을 제공합니다. 그 중에 캐시(cache)라는 개념이 있습니다. 캐시란 웹 페이지나 이미지 등의 자원을 일시적으로 저장해 두는 장소를 말합니다. 캐시를 이용하면 같은 자원을 반복해서 다운로드하지 않아도 되므로, 웹 페이지 로딩 속도를 향상시킬 수 있습니다.

HTTP/1.1은 다음과 같은 두 가지 유형의 캐시를 지원합니다.

  1. 프락시 캐시

프락시 캐시는 클라이언트와 서버 사이에 위치한 중개자 역할을 하는 프락시 서버에서 캐시를 유지합니다. 클라이언트가 자원을 요청하면, 프락시 서버는 자원이 캐시에 저장되어 있는지 확인합니다. 만약 캐시에 저장되어 있다면, 프락시 서버는 클라이언트에게 자원을 제공합니다. 이렇게 함으로써, 클라이언트는 서버로부터 자원을 다운로드할 필요 없이 프락시 서버에서 자원을 받아올 수 있습니다.

  1. 브라우저 캐시

브라우저 캐시는 클라이언트 측에서 자원을 저장하는 캐시입니다. 클라이언트가 자원을 요청하면, 브라우저는 자원이 캐시에 저장되어 있는지 확인합니다. 만약 캐시에 저장되어 있다면, 브라우저는 서버로부터 자원을 다운로드할 필요 없이 캐시에서 자원을 로딩할 수 있습니다.

캐시는 자원을 반복해서 다운로드하지 않아도 되므로, 웹 페이지 로딩 속도를 향상시킬 수 있습니다. 또한 캐시를 이용하면 서버의 부하를 줄일 수 있으며, 네트워크 대역폭을 절약할 수도 있습니다.

HOLB(Head Of Line Blocking) - 특정 응답 지연

  • Http Pipelining으로 하나의 connection을 통해 다수개의 파일을 Request/Response 받을 수 있지만 첫 번째 Response가 지연되면, 다음 두, 세번째 Response는 첫번째 응답처리가 완료되기 전까지 대기하게 되기 때문에 Head Of Line Blocking(HOLB)가 발생한다.
  • 연속된 요청의 헤더 중복

HTTP/1.1이 15년 이상 동안 안정성을 유지한 이유

  1. 호환성: HTTP/1.1은 이전 버전인 HTTP/1.0과의 하위 호환성을 제공합니다. 따라서, 이전에 작성된 코드나 어플리케이션들도 업그레이드 없이 그대로 사용할 수 있습니다.
  2. 향상된 성능: HTTP/1.1에서는 새로운 기능들이 추가되어 효율적인 성능을 보장합니다. 예를 들어, 지속적인 연결, 파이프라이닝, 청크 전송 등의 기능이 도입되어 네트워크 대역폭을 더욱 효율적으로 사용할 수 있습니다.
  3. 보안 강화: HTTP/1.1은 새로운 보안 기능을 제공하여 보안성을 강화했습니다. 예를 들어, SSL/TLS(HTTPS) 프로토콜의 적용, HTTP 쿠키의 보안 기능 도입 등이 있습니다.
  4. 표준화: HTTP/1.1은 IETF(Internet Engineering Task Force)에서 표준화된 프로토콜입니다. 이를 통해 다양한 플랫폼과 언어에서 쉽게 사용할 수 있으며, 보안성과 안정성도 보장됩니다.
  5. 개선을 위한 노력: HTTP/1.1의 안정성을 유지하기 위해서는 지속적인 개선과 유지보수가 필요합니다. 따라서, HTTP/1.1은 지속적으로 업데이트되고 개선되어 왔습니다.

따라서, HTTP/1.1이 15년 이상 동안 안정성을 유지한 것은 다양한 기능과 보안성을 갖추며, 지속적인 개선과 유지보수가 이루어졌기 때문입니다.


2.4 HTTP/2.0

2.4.1 특징

  • HTTP 메시지 전송 방식의 전환
  • Multiplexed Streams
  • Stream Prioritization
  • Server Push
  • Header Compression
- Stream: 구성된 연결 내에서 전달되는 바이트의 양방향 흐름, 하나 이상의 메시지가 전달 가능하다.
- Message: 논리적 요청 또는 응답 메시지에 매핑되는 프레임의 전체 시퀀스이다.
- Frame: Http/2.0에서 통신의 최소 단위, 각 최소 단위에는 하나의 프레임 헤더가 포함된다. 
				이 프레임 헤더는 최소한으로 프레임이 속하는 스트림을 식별한다. 
				Headers Type Frame, Data Type Frame이 존재한다.

HTTP 2.0은 HTTP 1.1 프로토콜을 계승해 동일한 API면서 성능 향상에 초점을 맞췄다.

HTTP 메시지 전송 방식의 전환

HTTP/1.1에서는 텍스트 기반으로 메시지를 주고받았습니다. 하지만 HTTP/2에서는 이를 바이너리 기반 프레임으로 변경하여, 더욱 빠르고 효율적인 전송이 가능하게 되었습니다. 이에 따라, HTTP/2는 더 빠른 웹 페이지 로딩 속도와 낮은 대기 시간을 제공할 수 있습니다.

HTTP/2에서는 메시지를 일정한 크기로 나누어서 전송하며, 각각의 메시지는 여러 개의 프레임으로 나누어져 전송됩니다. 이때, 각각의 프레임은 고유한 식별자를 가지고 있으며, 이를 통해 여러 개의 프레임이 하나의 메시지를 구성하고 있는지 확인할 수 있습니다.

HTTP/2에서는 이진 프로토콜을 사용하기 때문에, 이전 버전의 HTTP와 달리 메시지 해석을 위한 별도의 파싱 작업이 필요하지 않습니다. 이는 서버와 클라이언트 간에 더 적은 데이터 양을 주고받아도 되기 때문에, 전송 속도가 향상됩니다.

또한, HTTP/2에서는 이진 프레임 압축 기능을 제공합니다. 이를 통해 메시지를 전송하기 전에 압축을 수행하고, 수신측에서는 압축을 해제하여 메시지를 복원합니다. 이진 프레임 압축 기능을 사용하면, 전송해야 할 데이터의 양을 줄일 수 있으며, 전송 속도를 더욱 향상시킬 수 있습니다.

Multiplexed Streams

HTTP/2.0에서는 하나의 TCP 연결을 통해 여러 개의 요청과 응답을 동시에 처리할 수 있도록 Multiplexed Streams 기능을 제공합니다. 한 Connection으로 동시에 여러 개 메시지를 주고 받을 수 있으며, Response는 순서에 상관없이 stream으로 주고받습니다. 이 기능은 하나의 연결을 통해 동시에 여러 개의 요청과 응답을 처리할 수 있기 때문에, 웹 페이지의 로딩 속도를 빠르게 할 수 있습니다.

이전 버전에서는 하나의 TCP 연결로 한 번에 하나의 요청만 처리할 수 있었기 때문에, 웹 페이지에서 여러 개의 이미지나 파일을 다운로드하는 경우에는 이미지 스프라이트나 도메인 분할과 같은 방법을 사용하여 병목 현상을 완화해야 했습니다.

하지만 HTTP/2.0에서는 하나의 TCP 연결로 여러 개의 스트림을 동시에 전송할 수 있기 때문에, 이미지 스프라이트나 도메인 분할과 같은 임시방편을 사용하지 않아도 됩니다. 이를 통해 불필요한 요청을 줄이고, 전체적인 로딩 속도를 높일 수 있습니다.

스트림을 사용함으로써, 웹 페이지의 컨텐츠를 작은 단위로 분할하여 전송함으로써, 클라이언트는 동시에 여러 개의 스트림을 수신하고, 이를 병렬로 처리할 수 있게 됩니다. 이는 웹 페이지의 전송 속도와 성능을 높일 뿐만 아니라, 대역폭의 효율적인 사용을 가능케 합니다.

따라서 HTTP/2.0에서는 이미지 스프라이트나 도메인 분할과 같은 방법을 사용하지 않아도, 웹 페이지의 로딩 속도를 높일 수 있습니다.

이미지 스프라이트는 여러 개의 작은 이미지를 하나의 큰 이미지로 합쳐서 웹 페이지에서 사용하는 방법입니다. 예를 들어, 웹 페이지에서 여러 개의 아이콘 이미지를 사용하는 경우, 이 아이콘 이미지들을 모두 하나의 이미지로 합쳐서 사용하는 것입니다. 그리고 이 큰 이미지에서 각각의 아이콘 이미지를 보여주는 방식으로 웹 페이지를 구성합니다. 이 방법을 사용하면, 여러 개의 이미지를 다운로드하는 대신 하나의 이미지만 다운로드하면 되기 때문에 웹 페이지의 로딩 속도를 높일 수 있습니다.

도메인 분할은 웹 페이지에서 사용하는 자원(이미지, CSS, JavaScript 등)을 여러 개의 서로 다른 도메인으로 분할하여 사용하는 것입니다. 예를 들어, 웹 페이지에서 사용하는 자원을 a.example.com과 b.example.com이라는 두 개의 서로 다른 도메인으로 분할하여 사용하는 것입니다. 이 방법을 사용하면, 브라우저에서는 하나의 도메인에서 여러 개의 자원을 동시에 다운로드하지 않고, 각각의 도메인에서 하나의 자원만 다운로드하기 때문에, 웹 페이지의 로딩 속도를 높일 수 있습니다.

요약하자면, 이미지 스프라이트는 여러 개의 이미지를 합쳐서 하나의 이미지로 사용하는 것이고, 도메인 분할은 여러 개의 도메인으로 자원을 분할하여 사용하는 것입니다. 두 방법 모두 웹 페이지의 로딩 속도를 높일 수 있는 임시방편입니다. 하지만 HTTP/2.0에서는 스트림을 사용하여 이러한 방법들을 사용하지 않고도 효율적인 웹 페이지 로딩이 가능합니다.

Stream Prioritization (스트림 우선순위)

멀티플렉싱 스트림을 사용하여 여러 개의 요청과 응답을 동시에 처리할때, Stream Prioritization 기술을 사용하여 각각의 스트림에 우선순위를 부여할 수 있습니다.

Stream Prioritization은 클라이언트와 서버 간의 통신에서 중요한 요청과 응답을 먼저 처리하도록 하는 방법입니다. 이를 통해 중요한 요청과 응답을 먼저 처리하고, 덜 중요한 요청과 응답은 나중에 처리함으로써, 전체적인 성능을 향상시킬 수 있습니다.

HTTP/2에서는 각각의 스트림에 대해 31개의 우선순위 값을 가질 수 있습니다. 이러한 우선순위 값을 이용하여, 서버는 중요한 요청과 응답에 대해 더 높은 우선순위를 부여할 수 있습니다. 또한, 클라이언트는 스트림을 생성할 때, 각각의 스트림에 대해 우선순위 값을 부여할 수 있습니다.

Stream Prioritization을 사용하면, 중요한 요청과 응답에 대한 대기 시간을 최소화하고, 덜 중요한 요청과 응답은 나중에 처리함으로써, 전체적인 성능을 향상시킬 수 있습니다.

Server Push

HTTP/2.0에서는 서버에서 클라이언트가 요청하지 않은 리소스를 미리 보내는 Server Push 기능을 제공합니다. 이를 통해 웹 페이지의 로딩 속도를 높일 수 있습니다.

즉, 클라이언트가 요청하기 전에 필요하다고 예상되는 리소스를 Server에서 먼저 요청합니다.
예를 들어 http만 요청했는데 http와 css, js, image를 함께 전송해주는 것이죠.

Header Compression (헤더 압축)

HTTP/2에서는 헤더 압축 기술을 사용하여 헤더를 압축하여 전송함으로써 대역폭 사용을 최소화합니다. 이를 통해 더 빠른 속도와 효율적인 전송이 가능합니다.

HTTP/1.1에서는 각각의 요청과 응답마다 헤더 정보를 중복해서 전송합니다. 이는 대역폭 낭비로 이어지고, 전송 속도를 늦추는 원인이 됩니다. 하지만 HTTP/2에서는 중복되는 헤더 정보를 압축하여 전송함으로써, 대역폭을 절약할 수 있습니다.

HTTP/2에서는 헤더 정보를 HPACK(Hypertext Transfer Protocol version 2 Compression) 압축 방식을 사용하여 압축합니다. 이 방식은 헤더 정보를 동적인 테이블과 정적인 테이블로 분리하여 압축합니다. 동적인 테이블은 매 요청마다 변경되는 헤더 정보를 저장하는데 사용되며, 정적인 테이블은 미리 정의된 헤더 정보를 저장하는데 사용됩니다.

압축된 헤더 정보는 클라이언트와 서버 간에 전송되며, 수신 측에서는 압축된 헤더 정보를 해독하여 원래의 헤더 정보로 변환합니다. 이를 통해 대역폭을 절약할 수 있으며, 더욱 빠른 속도와 효율적인 전송이 가능합니다.

HTTP/1.0/1.1/2.0의 TCP 연결의 차이점

HTTP/1.0, 1.1 및 2.0은 모두 TCP를 기반으로합니다. 그러나 각 버전마다 연결 방식에 차이가 있습니다.

HTTP/1.0에서는 클라이언트가 서버에 요청을 보내면 서버가 응답 후에 연결을 끊습니다. 이러한 방식은 "1 요청 - 1 응답" 방식으로 알려져 있습니다. 이것은 "Connection: keep-alive" 헤더가 도입되기 전까지는 모든 요청마다 새로운 TCP 연결이 필요했다는 것을 의미합니다.

HTTP/1.1에서는 "Connection: keep-alive" 헤더가 도입되어 여러 요청을 한 번의 연결로 처리할 수 있게 되었습니다. 이 방식은 "HTTP Persistent Connections" 또는 "HTTP Keep-Alive"라고도합니다.

그러나 HTTP/1.1에서도 여전히 여러 요청을 동시에 처리하지 못하고, 하나의 요청-응답 사이클이 완료되어야 다음 요청을 처리할 수 있습니다. 이는 HOLB(Head Of Line Blocking)이라고도 알려져 있습니다.

반면, HTTP/2.0에서는 하나의 TCP 연결을 통해 여러 개의 요청 및 응답을 병렬로 처리할 수 있습니다. 이를 통해 HOLB 문제를 해결하고 전체적인 성능을 향상시킬 수 있습니다. 또한, HTTP/2.0에서는 요청 및 응답을 바이너리 프레임으로 분할하여 전송하므로 헤더 압축과 다중화를 이용한 전송 최적화도 가능합니다.

따라서, HTTP/1.0과 1.1은 여러 번의 연결을 필요로 하거나, HOLB 문제가 발생할 가능성이 높습니다. 반면, HTTP/2.0은 단일 연결을 통해 병렬로 처리가 가능하고, 바이너리 프레임 및 헤더 압축과 같은 기능을 제공하여 전송 효율성을 높입니다.


HTTP 2.0 한계와 해결책

HTTP/2.0은 이전 버전인 HTTP/1.1과 비교하여 많은 개선 사항을 가지고 있습니다. 그러나 여전히 몇 가지 한계가 있습니다.

  1. SSL/TLS 암호화
    HTTP/2.0은 기본적으로 SSL/TLS를 요구하며, 암호화되지 않은 HTTP/2.0 연결을 허용하지 않습니다. 이것은 기존의 HTTP/1.x와는 큰 차이점 중 하나입니다.

    HTTP/2.0에서 SSL/TLS를 사용함으로써, 네트워크를 통한 데이터 전송 과정에서 데이터가 변조되거나 도난당하는 것을 방지할 수 있습니다. SSL/TLS는 대칭키 암호화와 공개키 암호화를 혼합하여 사용하여, 데이터를 안전하게 전송할 수 있습니다.
    
    하지만 SSL/TLS를 사용하면 추가적인 부하와 더 많은 리소스가 필요합니다. 서버 측에서 SSL/TLS 인증서를 설치해야 하며, 이는 비용이 들기도 합니다. 또한 SSL/TLS 연결 설정 시간이 필요하므로, 연결 설정 시간이 늘어나는 단점이 있습니다.
    
    하지만 이러한 단점을 극복하기 위해 SSL/TLS 인증서를 발급하는 기관에서는 무료 SSL/TLS 인증서를 제공하기도 합니다. 또한 SSL/TLS 성능 개선을 위한 여러 기술들도 개발되어 있습니다. 예를 들어, SSL/TLS 핸드셰이크를 개선하는 TLS False Start, SSL/TLS 암호화/복호화의 성능을 향상시키는 AES-NI 등이 있습니다. 따라서 SSL/TLS를 사용하면서도, 이러한 기술들을 활용하여 성능을 최적화할 수 있습니다.
  2. 호환성
    HTTP/2.0은 새로운 프로토콜이기 때문에 모든 브라우저와 서버가 지원되지 않을 수 있습니다. 이 경우 HTTP/1.1 프로토콜을 사용해야 하므로 더 많은 네트워크 지연이 발생할 수 있습니다.

    이러한 문제를 해결하기 위한 몇 가지 방법이 있습니다. 
    
    첫째, HTTP/2.0이 지원되지 않는 브라우저나 서버의 경우, HTTP/1.1을 사용하는 대신 HTTP/1.1의 최신 기능과 최적화된 구현을 사용할 수 있습니다. 이를 통해 성능을 향상시킬 수 있습니다.
    
    둘째, 프록시 서버를 사용하여 HTTP/2.0 요청을 HTTP/1.1 요청으로 변환할 수 있습니다. 이는 클라이언트가 HTTP/2.0을 지원하지 않더라도 HTTP/2.0을 사용하는 것과 동일한 이점을 제공합니다.
    
    셋째, 서버 측에서는 HTTP/2.0을 지원하는 브라우저에 대해서만 HTTP/2.0을 사용하도록 구성할 수 있습니다. 이를 통해 HTTP/1.1 요청과 HTTP/2.0 요청을 모두 처리할 수 있습니다.
  3. 서버 리소스

    HTTP/2.0에서는 다중화 및 헤더 압축 기능을 사용하여 네트워크 대역폭을 효율적으로 사용할 수 있습니다. 그러나 이러한 기능들은 서버 측에서 더 많은 리소스를 필요로 합니다.

    먼저, 다중화 기능은 하나의 TCP 연결을 통해 여러 개의 HTTP 요청과 응답을 처리하기 때문에 서버 측에서는 더 많은 커넥션을 처리할 필요가 없어졌습니다. 하지만 이는 하나의 연결에 여러 개의 요청이 동시에 처리되기 때문에 서버의 처리량이 증가하게 됩니다. 따라서, 서버 측에서는 적절한 리소스를 할당하여 다중화 기능을 지원해야 합니다.

    또한, 헤더 압축 기능은 서버 측에서 더 많은 리소스를 필요로 합니다. 헤더 압축은 메모리와 CPU를 많이 사용하므로, 서버에서는 적절한 메모리 및 CPU 리소스를 할당하여 헤더 압축 기능을 지원해야 합니다.

    특히, 메모리가 제한된 서버에서는 이러한 기능들을 지원하기 위해 추가적인 하드웨어 리소스가 필요할 수 있습니다. 이를 해결하기 위해서는 서버의 스펙을 적절하게 업그레이드하여 리소스를 늘리는 것이 필요합니다. 또한, 캐싱 기능을 활용하여 중복 요청을 최소화하고, 적절한 로드 밸런싱을 수행하여 서버 리소스를 효율적으로 활용할 수 있습니다.

  4. 대역폭 요구사항

    HTTP/2.0은 다중화 기능을 통해 여러 개의 요청을 동시에 처리할 수 있기 때문에, 동시에 처리되는 요청이 많을수록 대역폭 사용량이 높아지게 됩니다. 이러한 특성 때문에, HTTP/2.0을 사용하는 경우 대역폭 요구사항이 높아질 수 있습니다.

    네트워크 대역폭이 제한된 경우, HTTP/2.0을 사용하는 것이 HTTP/1.1보다 더 느릴 수 있습니다. 이를 해결하기 위해서는 다음과 같은 방법들이 있습니다.

    • 서버 사이드에서 리소스 최적화: 대역폭을 절약할 수 있는 최적화된 리소스, 예를 들면 이미지 크기를 줄이거나 CSS/JS 파일을 압축하는 등의 방법을 사용하여 리소스를 최적화할 수 있습니다. 이렇게 하면 페이지 로드 속도를 높이고 대역폭을 절약할 수 있습니다.
    • 캐싱: 캐싱은 서버의 대역폭을 절약하는 데 매우 유용합니다. 브라우저 캐시와 같은 기존의 캐싱 방법 외에도, HTTP/2.0에서는 서버 푸시(push)를 지원하므로, 서버에서 클라이언트로 리소스를 미리 보내 캐시를 미리 채울 수 있습니다.
    • 프로토콜 설정: HTTP/2.0은 다양한 설정 옵션을 제공합니다. 예를 들어, 클라이언트는 서버에 대해 최대 동시 스트림 수를 지정할 수 있습니다. 서버 측에서는 허용되는 동시 스트림 수와 우선 순위 설정 등을 통해 대역폭을 효율적으로 사용할 수 있습니다.
    • 대역폭 증설: 대역폭을 증설하여 HTTP/2.0의 효과를 높일 수 있습니다. 하지만 이는 추가적인 비용이 들어가며, 대역폭 증설이 불가능한 경우도 있습니다.
  5. 무거운 헤더

    HTTP/2.0의 헤더는 이전 버전에 비해 크기가 더 크기 때문에 대역폭을 많이 사용할 수 있습니다. HTTP/2.0는 이러한 헤더를 압축하고 바이너리 프레임으로 전송하여 대역폭을 줄이지만, 일부 큰 헤더는 여전히 압축이 잘 되지 않을 수 있습니다. 예를 들어, 쿠키와 같은 긴 문자열은 압축하기 어렵습니다.

    해결책으로는 헤더 크기를 줄이는 것입니다. 이를 위해서는 다음과 같은 방법을 사용할 수 있습니다.

    • 캐싱을 사용합니다.
      HTTP 캐싱을 사용하면 리소스를 캐시할 수 있으므로 서버로부터 다시 전송할 필요가 없어서 헤더 크기를 줄일 수 있습니다.
    • 쿠키 크기를 줄입니다.
      쿠키는 긴 문자열이 포함될 수 있으므로 쿠키 크기를 줄이는 것이 좋습니다. 예를 들어, 쿠키 대신 Local Storage와 같은 HTML5 스토리지 메커니즘을 사용할 수 있습니다.
    • HTTP/2.0 서버 푸시를 사용합니다.
      HTTP/2.0 서버 푸시를 사용하면 클라이언트 요청에 대한 리소스를 서버에서 미리 푸시할 수 있습니다. 이를 통해 서버는 클라이언트로부터 요청을 받을 필요가 없으므로 헤더 크기를 줄일 수 있습니다.
    • 서버 측에서 헤더 압축을 효과적으로 구현합니다.
      HTTP/2.0에서는 헤더 압축 알고리즘이 필수적으로 사용되기 때문에 서버 측에서 이를 효과적으로 구현하는 것이 중요합니다. 이를 위해 서버 측에서는 헤더를 최소한으로 유지하고, 필요한 경우 헤더를 결합하거나 분할하는 등의 방법을 사용하여 헤더 크기를 줄입니다. 또한, 서버 측에서는 헤더 압축 알고리즘을 최적화하는 것도 중요합니다.
  6. TCP 고유의 HOL Blocking

    HTTP/2.0에서는 다중 스트림을 사용하여 병렬로 처리함으로써 여러 요청을 동시에 처리할 수 있게 되었지만, 여전히 TCP의 HOL(Block) Blocking 문제를 완전히 해결하지 못했습니다. 이는 하나의 스트림에서 문제가 발생하면 해당 스트림 이후의 모든 스트림들이 지연되어 처리되는 현상이 발생하기 때문입니다.

    QUIC(HTTP3.0)는 TCP와는 다른 전송 계층 프로토콜로서, UDP 기반으로 동작하며, HOL Blocking 문제를 해결하기 위한 다양한 기술들이 적용되어 있습니다. QUIC은 데이터를 보내는 스트림과 통신을 하는 스트림을 분리하여 처리하며, 스트림 간에 독립적인 패킷 전송 및 처리를 가능하게 합니다. 또한, 스트림을 처리하기 위한 고유한 ID를 부여하여 HOL Blocking 문제를 완전히 해결할 수 있습니다.

    따라서, HTTP/2.0에서 발생하는 TCP의 HOL Blocking 문제를 해결하기 위해 QUIC(HTTP3.0)이 등장하였으며, 이는 다양한 기술들을 적용하여 병렬 처리 및 지연 문제를 해결하고 있습니다.

2.5 HTTP/3.0

2.5.1 특징

  • UDP 기반의 전송 프로토콜 (Quick UDP Internet Connections)
  • 에러 복구
  • 레이턴시 감소
  • HOLB 해결

QUIC

HTTP/3.0은 기존의 TCP 대신에 QUIC (Quick UDP Internet Connections) 프로토콜을 사용합니다. QUIC은 TCP와 UDP를 결합하여 개발된 프로토콜로, 빠른 전송 속도와 신뢰성 있는 데이터 전송을 보장합니다. 또한, TLS (Transport Layer Security) 프로토콜과 통합되어 있어 보안성도 높습니다.

에러 복구

HTTP/3.0은 에러 복구를 위한 메커니즘을 강화했습니다. 이전 버전의 HTTP에서는 오류가 발생하면 연결을 다시 시작해야 했지만, HTTP/3.0에서는 오류가 발생해도 연결을 유지할 수 있습니다. 이를 통해, 빠른 인터넷 연결이 중단되는 상황에서도 사용자 경험을 개선할 수 있습니다.

레이턴시 감소

HTTP/3.0은 레이턴시 감소를 위한 몇 가지 기능을 추가했습니다. 레이턴시란 데이터가 전송되는 데 걸리는 시간을 의미하며, 인터넷 연결이 느린 경우 사용자 경험에 직접적인 영향을 미칩니다. HTTP/3.0에서는 요청과 응답을 처리하는 방식이 변경되어 레이턴시를 감소시킬 수 있습니다.

HOLB 해결

HTTP/3.0은 HOLB (Head-of-line blocking) 문제를 해결하기 위해 다중화 기능을 강화했습니다. 이전 버전에서는 하나의 데이터 패킷이 손실되면 전체 패킷 전송이 지연되었지만, HTTP/3.0에서는 여러 개의 데이터 스트림을 병렬적으로 처리하여 HOLB 문제를 해결할 수 있습니다.

따라서, HTTP/3.0은 기존 버전과 달리 UDP를 사용하고, 에러 복구, 레이턴시 감소, HOLB 문제 해결 등을 위한 다양한 기능을 추가하여 더욱 빠르고 신뢰성 있는 데이터 전송을 가능하게 합니다.


Reference

https://datatracker.ietf.org/doc/html/rfc7230#page-79
https://inpa.tistory.com/entry/WEB-🌐-HTTP-30-통신-기술-이제는-확실히-이해하자
https://web.dev/performance-http2/
https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP
ChatGPT

profile
데이터리터러시를 중요하게 생각하는 프론트엔드 개발자

0개의 댓글