- header가 없음
1.0 에서 개선
- GET 요청만 존재
1.0 에서 개선
- HTML 파일만 주고 받을 수 있음
1.0에서 개선
- 상태코드 없음
1.0에서 개선
- 단일 라인으로 요청과 응답을 처리
1.1, 2.0, 3.0에서 개선
/* 요청 */
GET /mypage.html
/* 응답 */
<HTML>
A very simple HTML page
</HTML>
- header 개념 도입으로 요청 및 응답에 메타데이터 전송이 가능하며 확장도 가능
- 버전 정보와 Method 명도 함께 전송
- HTML 파일 이외의 파일도 전송 가능
- 상태 코드 도입, 최상단에 위치
/* 요청 */
GET /mypage.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
/* 응답 */
200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
A page with an image
<IMG SRC="/myimage.gif">
</HTML>
- 커넥션 하나당 요청 하나와 응답 하나만 처리
1.1에서 개선
- Persistent Connection
- 지정한 timemout 동안 커넥션을 닫지 않는 방법을 통해 커넥션의 사용성이 높아짐
- Pipelining
- 요청 -> 응답 -> 요청 -> 응답 -> ... 와 같이 동기적인 요청/응답 방식을 개선하기 위함
- 필요한 요청들을 한번에 보내고 순차적으로 응답을 받음
/* 요청 */
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
/* 응답 */
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)
- Head Of Line Blocking (HOL)
2.0 에서 개선
- 이전 요청의 응답이 오래 걸리면 뒤 요청은 처리될 때 까지 대기(Blocking)
- Header 구조의 중복
2.0 에서 개선
- 연속된 요청의 헤더의 많은 중복이 발생
HTTP 메시지 전송 방식의 전환
Binary Framing 계층을 추가해, 보내는 메시지를 프레임(frame) 단위로 분할 후
바이너리로 인코딩파싱 및 전송 속도 빨라짐
- Multiplexed Streams
Head Of Line Blocking (HOL) 문제 해결
- HTTP 1.1의 Pipelining은 여러 요청을 한번에 보내지만 응답은 순차적으로 받음
- 이를 개선하기 위해 하나의 커넥션에 여러 Stream을 두어 해결
- Stream 별로 요청/전송을 하기 때문에 도착 순서의 중요성이 없어짐
- Stream Prioritization
- 리소스간 우선순위를 설정하는 기능
- Stream에 우선순위를 부여해서 Interleaving(끼여들기)되어 전달 가능
- Server Push
- Server에서 client에게 필요한 추가적인 리소스를 요청 전에 미리 보내주는 기능
- ex) HTML의 link 태그 내부의 파일들(CSS, JS)
- Header Compression
- 요청과 응답의 헤더 메타데이터를 압축해서 오버헤드를 감소
- 전송되는 헤더 필드를 static dynamic table로 서버에서 유지
- 이전에 표시된 헤더를 제외한 필드를 허프만(huffman) 인코딩을 수행해서 데이터를 압축
- TCP의 HOL Blocking
QUIC 에서 개선
- 하나의 Stream에서 유실 혹은 오류가 발생한 경우, 다른 Stream은 이 문제가 해결될 때까지 지연
- Google에서 개발한 UDP 기반의 전송 계층 프로토콜 (Quick UDP Internet Connections)
- HTTP는 응용 계층 프로토콜
- QUIC을 기반으로 하여
HTTP 3.0
이 탄생
- TLS 보안 기본 적용
- QUIC은 TCP의 3-way handshake과정을 최적화 하는 것에 초점을 두고 개발됨
- 첫 커넥션 연결 요청 시 이후 요청할 데이터도 함께 보냄
- 연결 성공 시 Connection UUID 를 캐싱하고 다음 연결 때 재사용하여 연결
전송 속도 향상
- 독립 스트림
- TCP의 Stream은 하나의 chain으로 연결되는 것과 다르게
각 Stream당 독립된 Stream chain을 구성하여 TCP HOL Blocking을 해결[기존]
[개선]
- 기존 체계 호환성 문제
- HTTP/1.1 이나 HTTP/2 기반의 프론트엔드단 최적화를 적용한 기업의 경우 QUIC 도입 부담
- 예를 들어 브라우저의 병렬 다운로드를 통해 리소스를 빠르게 받아오는 도메인 분할(domain sharding) 기법을 이미 적용하여 최적화를 시킨 기업은 오히려 멀티플렉싱 기반의 HTTP/2 혹은 HTTP/3에서 성능 반감
- 브라우저의 콘텐츠 Prefetch 기능을 적용한 경우, 이를 Server Push 기능으로 변경해야 할지에 대한 기술적인 판단과 충분한 성능 비교 테스트가 필요
- 암호화로 네트워크 제어가 힘듬
- QUIC는 기존에는 암호화하지 않던 헤더 필드도 암호화
- ISP나 네트워크 중계회사들은 기존에 암호화하지 않던 헤더 필드 영역들을 읽을 수 없어 네트워크 혼잡을 관리하기 위한 네트워크를 최적화하기 힘듦.
- 예를 들어 패킷이 ACK인지 재전송인지 알 수 없음. RTT 추정은 더 어려움.
- 암호화로 리소스가 많이 듬
- QUIC은 패킷별로 암호화
- 기존의 TLS-TCP에서 패킷을 묶어서 암호화하는 것보다 더 큰 리소스 소모
- QUIC는 CPU를 너무 사용함
- 보급형 스마트폰과 IoT 장치같은 마이크로 애플리케이션들은 이용에 어려움을 겪을 수도 있다.
- UDP의 보안적인 문제
- DNS에서 TCP나 UDP를 53포트를 이용해 통신
- 53 포트가 아닌 UDP 트래픽이 최근에는 도스 공격에 주로 사용되기 때문에 많은 서비스들에서 차단하거나 속도를 제한
- 그래서 QUIC에서는 초기 패킷이 최소 1200바이트여야 한다는 조건과 서버가 클라이언트로부터 응답 패킷을 받지 않으면 요청 크기의 3배 이상은 절대 보내면 안 된다는 프로토콜의 제약사항으로 이를 해결하려고 노력 중
- QUIC의 한계는 어떤 게 있을까?
24.04.22 추가
- UDP 기반의 프로토콜에서 TCP 처럼 신뢰성을 확보하기 위해 어떤 것을 했을까?
https://velog.io/@beberiche/QUIC#quic-%EC%9D%98-%EC%8B%A0%EB%A2%B0%EC%84%B1-%EB%B3%B4%EC%9E%A5