본문 바로가기
ComputerScience/Network

[Network] 4. HTTP 버전 & QUIC

by Develaniper 2021. 5. 28.

1. 개요

HTTP프로토콜은 TCP/IP 환경에서 동작한다고 알고있다. 하지만 HTTP가 TCP프로토콜에서 동작하는게 맞는 말일까?

 

위키백과

 

HTTP(HyperText Transfer Protocol, 문화어: 초본문전송규약, 하이퍼본문전송규약)는 W3 상에서 정보를 주고받을 수 있는 프로토콜이다. 주로 HTML 문서를 주고받는 데에 쓰인다. 주로 TCP를 사용하고 HTTP/3 부터는 UDP를 사용하며, 80번 포트를 사용한다.

 그렇다. http프로토콜은 TCP가 필요한 것이 아니라 신뢰성을 보장하는 프로토콜이 필요한 것이었고, TCP보다 효율적으로 전송할 수 있는 UDP가 신뢰성 까지 보장한다면 TCP를 사용할 이유가 없을 것이다.

 

이 사실을 모른 채 HTTP에 대한 대화를 나누다 http는 tcp에서만 동작하나요? 라는 질문을 받게 된다면 그런것 같다는 대답을 하게 될 것이다.

 

이번 포스트는 HTTP의 버전별 그리고 QUIC의 차이를 비교하며 그 특징들에 대해 살펴볼 것이다.

 

 

HTTP

 TCP프로토콜을 사용하는 Application의 계층들은 신뢰성을 보장하는 전송계층의 프로토콜을 사용할 수 있음

 

2. HTTP/0.9~2

1) HTTP/0.9 - One Line Protocol

- 요청

GET /page.html

- 응답

<HTML>
  내용~~
</HTML>

 

  •  버전번호가 따로 없었지만 1.0이상의 버전들과 구분하기위해 0.9 버전을 붙이게 되었다.
  • GET메서드만이 존재했으며 Header도 없었고 오직 HTML 파일만 전송 가능했다.
  • 상태확인 코드도 존재하지 않았다.
  • 이런 특성 때문에 One-Line Protocol 이라고 부르기도 함.

 

2) HTTP/1.0 - 확장성 구축

 본격적인 HTTP라고 할 수 있다.

  • 요청에 버전 정보가 붙어서 전송되기 시작
  • 응답 시작 부분에 상태 코드 추가되어 요청 결과를 알 수 있게 됨
  • 모든 요청과 응답에 헤더 개념이 추가됨
  • 헤더에 Content-Type이 추가되어 HTML 파일 외 다른 문서 전송도 가능

- 문제점(한계)

 단기 커넥션 : Connection 하나당 요청1개와 응답 1개만 처리 가능하다. 이는 서버부하에 따른 성능저하로 비용이 증가한다는 문제점이 있다.

3) HTTP/1.1 - 표준 프로토콜

- 요청(velog.io/@leejaylight 참조)

GET /en-US/docs/Glossary/Simple_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header

- 응답(velog.io/@leejaylight 참조)

200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
(content)
  • 지속 커넥션(Persistent connection) 도입. Timeout이 되기전에는 Connection을 닫지 않으며 여러개의 요청이 커넥션 사용 가능함. -> 1.0에 비해 네트워크 시간 줄어듦
  • Pipelining 도입, 이전 요청에 대한 응답이 완전 전송되기 전에 다음 전송을 가능하게 하여 지연시간(Latency)를 낮춤

 

short-lived, persistent, pipelining 비교

  • short-lived connection
    3번의 요청을 연달아 해야하는 상황임에도 불구하고 연결과 종료를 각각 진행하고 있다.
  • persistent connection
    연달아 하는 요청일 경우 한번 connection을 하고 요청을 마친 후 connection을 종료하고 있다.
    Keep-alive와 관련있다.
  • HTTP pipelining
    persistent connection을 기반으로 요청에 대한 응답이 올때 까지 기다리지 않고 모든 요청을 미리 보내 놓고 응답이 오는대로 받는 것이다.

세가지 방식을 비교해 보면 그림으로도 속도차이가 확실하게 난다는 것을 볼 수 있다. 뿐만아니라 Handshake에서 소모되는 시간을 생각하면 short-lived에서 persistent connection으로 발전하면 월등한 속도 증가가 일어났을 것이다.

 

- 문제점(한계)

  • Head of Line Blocking
    선해 요청이 오래걸릴 경우 이후 요청의 대기시간이 길어진다. 예를 들면 위 그림에서 화살표 별로 1,2,3번 요청이라고 할때, 1번의 처리시간이 길어진다면 server에서 client로 향하는 2,3번 화살표는 더욱 아래쪽에서 시작할 것이다.
  • Header 구조 중복
    여러 요청을 주고 받을 때 Header에 중복되는 내용이 많더라도 요청마다 매번 같은 내용을 주고 받아야하므로 데이터 양이 불필요하게 커짐

4) HTTP/2.0 - 1.1의 성능 개선

2015년 표준화 됐으며 1.1에서 기능 확장 중심으로 개선, 2021년 3월 기준 약 50%의 웹 사이트가 채택함

developers.google

  • 메시지 전송 형태의 변화 - 바이너리
    - HTTP 메시지가 캡슐화 되어 클라이언트와 서버 사이에 전송됨
    - 기존 텍스트로 메시지를 전송하던 방식에서 바이너리 프레이밍 계층을 사용하는 방식으로 변화
    -  줄바꿈으로 구분되는 일반 텍스트 HTTP/1.x 와 달리, HTTP/2는 더 작은 메시지와 프레임 단위로 분할하여, 각 프레임을 바이너리 형식으로 인코딩하여 전송
    - 바이너리 친화적인 컴퓨터의 특성덕에 전송속도 증가와 오류율이 낮아짐.

  • 스트림, 메시지 및 프레임
    - HTTP/2는 HTTP 프로토콜 통신을 바이너리 인코딩된 프레임의 교환의 과정입니다.
    - 전달된 프레임들은 특정 스트림에 속하는 메시지로 매핑되며, 모든 프레임은 TCP 연결 내에서 다중화 됩니다.(하나의 메시지가 여러 프레임으로 나뉘는 것을 말하는 것같다.)
- 각 용어의 뜻은 다음과 같다. google의 공식문서의 내용을 적었고 괄호는 필자의 해석이다.
- 스트림
 연결 내에서 전달되는 바이트의 양방양 흐름이며, 하나 이상의 메시지가 전달될 수 있다.(한번 요청으로 )
- 메시지
논리적 요청 또는 응답 메시지로 매핑되는 프레임의 전체 시퀀스(헤더, 응답메시지/ 요청메시지)
- 프레임
HTTP/2 통신의 최소 단위로 프레임당 최소단위의 프레임 헤더가 포함된다. ( 프레임은 메시지를 전송하기 위한 분할 단위이다.)

  • 멀티 플렉싱
    - 바이너리 프레이밍 계층은 HTTP/1.x에서 Head-Of-Line(HOL) 차단과 기본 TCP연결의 비효율적인 사용을 초래하는 는 제한을 없애고 응답 다중화를 지원한다.
    - 이를 위해 Client와 Server가 HTTP 메시지를 독립된 프레임으로 세분화 하고, 이 프레임을 인터리빙 한 후 다른 쪽에서 재조립하도록 허용한다.
    - 위 그림은 Client가 Data프레임(stream 5)을 서버로전송 중일 때, 서버는 스트림 1과 스트림 3의 인터리빙(끼워넣기)된 프레임 시퀀스를 Client로 전송중이다. 즉, 3개의 병렬 스트림이 존재한다.

※인터리빙

 인터리빙은 위 그림에서와 같이  stream이 순서대로 가지 않고 사이에 끼어서 간다는 의미로 stream1과 stream1사이에 stream3 2개가 끼어 있는 것을 보면 알수 있다. 이로서 Head Of Line의 문제점을 해결할 수 있다. (메시지간 순서가 사라짐)

- 인터리빙으로 인한 장점

  1. 여러 요청/응답을 차단없이 병렬로 인터리빙 가능
  2. 단일 연결을 사용하며 여러 요청/응답을 병렬로 전달 가능
  3. 불필요한 지연을 제거하고 네트워크 용량의 활용도를 개선하여 페이지 로드시간을 줄임

  • ServerPush
    - HTTP/2에서 새로 추가된 강력한 기능 중 하나로 Server가 Client의 하나의 요청에 대해 여러 응답을 보낼 수 있는 것이다.
    - Client의 요청에 대해 미래에 어차피 요청할 것에 대해 현재 응답과 함께 응답해 버린다는 것이다.
    - 만일 데이터 URI를 통해 CSS, JS 또는 기타 자산을 인라인 처리한적 있다면 이미 서버푸시를 경험한 것이다.
    - 위 그림에서 stream1에 대한 요청을 받고 Client가 요청할 것으로 예상되는 2,4번 stream을 서버가 판단하여 Client로 푸시 하는 것이다.

- 서버푸시를 하는 경우

  1. 클라이언트에 의해 캐시됨( 같은 요청을 받은 적 있음)
  2. 다른 페이지에서 재사용
  3. 다른 리소스와 함께 다중화
  4. 서버에서 우선순위 지정
  5. 클라이언트에 의한 거부

 

  • 헤더 압축
    - HTTP/1.x 에서는 전송 리소스와 그속성명을 헤더세트에 전달함, 이에 따라 전송마다 Header가 겹처 오버헤드의 문제점이 있었다.
    - 2가지의 기술을 사용해 압축을 하는데 2가지의 기술은 다음과 같다.
    1) 헤더 필드를 정적 Huffman 코드로 인코딩하도록 허용(Huffman 코드-> 가변길이코드)
    2) 이전 헤더 필드의 색인 목록을 클라이언트와 서버가 유지하고 업데이트 하도록 요구
    - 1번째 헤더 이후로는 중복된 값은 인덱스목록만사용하고, 변경된 데이터 값에 대해서만 Huffman인코딩을 하여 전송한다.
    - 이에 따라 헤더의 크기가 줄어들었고 페이지 로드시간도 대폭 감소되었다

3. QUIC, HTTP/3

http 버전을 알아보는데 갑자기 QUIC?

QUIC은 UDP 기반으로 TCP+TSL+HTTP의 기능을 모두 구현하는 프로토콜이다.

 

구글이 TCP가 아닌 UDP를 선택한 이유는 TCP는 수정하기 어려운 반면 UDP는 사용할 여지가 많았기 때문이다.

위키백과
위키백과

확인해 보면 UDP에 비해 TCP는 굉장히 복잡한 것을 알 수 있다.

 

- QUIC의 특징

  • RTT(Round Trip Time)감소로 인한 지연시간단축
    • RTT는 시작지점에서 대상 지점으로 이동한 후 다시 시작지점으로 이동하는 시간을 말함
    • TCP가아니기 때문에 3Way Handshake과정을 거치지 않는다.
    • TCP는 연결을위해 1RTT, TLS를 사용한 암호화 까지 더하면 총 3RTT가 필요함
    • 반면 QUIC은 첫 연결 설정에 1RTT만 소요됨(처음에 연결설정에 필요한 정보와 함께 데이터도 보내기 때문)
    • 한번 연결에 성공하면 서버가 그 설정을 캐싱해 놓고 있어 다음연결에는 0RTT만에 통신 가능
  • 패킷 손실 감지에 걸리는 시간 단축
    • TCP는 Stop and Wait ARQ방식 사용 (송신측에서 패킷 보낸 후 타이머 설정 시간이 지나 답변 없으면 재전송)
    • QUIC은 헤더에 별도의 패킷 번호 공간을 부여해 고유번호를 가지고 있으므로 손실 감지에 걸리는 시간을 단축한다.
  • 멀티플렉싱 지원
  • 클라이언트의 IP가 바뀌어도 연결이 유지됨
    • TCP의 경우 IP주소와 포트기반으로 식별하여 IP가 바뀌면 연결이 끊어진다(Wi-Fi 전환, 셀룰러 전환으로 ip변경이 잦음)
    • QUIC의 경우 Connection ID(랜덤한 값)를 사용하여 서버와 연결하여 IP값이 변경되더라도 새로 연결 할 때 핸드쉐이크 과정을 생략할 수 있다.

 

오늘은 직접 표현하기 힘든 표가 많아 developers.google.com에서 많이 가져왔다.

또한 아래 동영상이 많은 도움이 되었다.

https://www.youtube.com/watch?v=xcrjamphIp4&t=448s 

https://velog.io/@ziyoonee/HTTP1-부터-HTTP3-까지-알아보기
https://jobjava00.github.io/basic/http-version/
https://velog.io/@leejaylight/네트워크-HTTP0.9-HTTP2-QUIC
https://developers.google.com/web/fundamentals/performance/http2?hl=ko
https://velog.io/@ziyoonee/HTTP1-부터-HTTP3-까지-알아보기



댓글