Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- webhacking
- 챗GPT
- c++
- mysql
- flask
- Scala
- hackerschool
- 경제
- 웹해킹
- php
- hackthissite
- 러닝 스칼라
- Web
- Python
- Javascript
- 딥러닝
- BOF
- Linux
- deep learning
- BOF 원정대
- 인공지능
- c
- 백엔드
- 리눅스
- backend
- Shellcode
- 파이썬
- ChatGPT
- hacking
- 러닝스칼라
Archives
- Today
- Total
jam 블로그
HTTP/3 (HTTP Protocol 발전 과정) 본문
728x90
HTTP/3
2019년 9월 정도에 새로운 웹 표준인 HTTP/3에 대한 지원을 발표하였습니다.
파트 내에서 웹 로딩 및 접근 속도를 위해서 조사를 하였습니다.
HTTP Protocol 발전 과정
요약
HTTP/0.9
HTTP 초기 버전에는 버전 번호가 없지만 추후 버전과 구별을 위해 붙여졌습니다.
- 특징
- GET 메소드만 존재
- HTTP 헤더가 존재하지 않음
HTTP/1.0
0.9버전에서 브라우저와 서버 모두 융통성을 가지도록 확장되었습니다.
- 특징
- 버전 정보가 각 요청 사이내로 전송되기 시작 (HTTP/1.0 GET
~) - HTTP Status code가 라인 또는 시작 부분에 붙어 전송
- 브라우저의 요청에 대한 성공 실패 여부 확인 및 그에 따른 동작
- HTTP 헤더 개념이 요청, 응답 모두에 도입
- 메타 데이터 전송을 허용
- 프로토콜을 극도로 유연하고 확장 가능
- HTML 파일들 외에 다른 문서들을 전송하는 기능 추가 (Content-Type)
- 버전 정보가 각 요청 사이내로 전송되기 시작 (HTTP/1.0 GET
HTTP/1.1
1.0이 나온지 몇달 안되고 나서 발표 되었으며, 많은 개선 사항을 도입되었습니다.
- 특징
- 커넥션 재사용
- 탐색된 단일 원본 문서 내로 임베드된 리소스들을 디스플레이하기 위해 사용된 커넥션을 다시 열어 시간 절약
- 파이프라이닝 추가
- 커뮤니케이션 레이턴시를 낮춤
- 첫번째 요청에 대한 응답이 완전히 전송되지 전에 두번째 요청 전송을 가능케 함
- 커뮤니케이션 레이턴시를 낮춤
- 청크된 응답 지원
- 캐시 제어 메커니즘 도입
- 언어, 인코딩 혹은 타입을 포함한 컨텐츠 협상 도입
- 클라이언트와 서버로 하여금 교환하려는 가장 적합한 컨텐츠에 대한 동의를 가능케 함
- Host 헤더 추가
- 동일 IP 주소에 다른 도메인을 호스트 하는 기능
- 커넥션 재사용
- 기타
- HTTPS
- SSL(Secure Sockets Layer, 보안 소켓 계층) : 웹사이트와 브라우저 사이에 전송된 데이터를 암호화하여 보안을 유지하는 표준 기술
- TLS(Transport Layer Security, 전송 계층 보안) : SSL의 상위 기술, SSL 3.0버전에서 취약점을 고친 버전으로 버전이 올라갈 때마다 암호화 알고리즘을 강력한 것으로 변경합니다. (현재는 1.3버전 진행 중)
- REST
- API에 의해 유도되는 액션들은 새로운 HTTP 메소드 뿐만 아니라, 기초적인 HTTP/1.1 메소드를 이용
- Same-Origin 정책
- HTTPS
HTTP/2
Google에서 응답 속도를 개선을 위해서 SPDY 프로토콜을 구현하였으며, 속도 개선의 가능성과 데이터 중복에 관한 문제를 해결하면서 HTTP/2로 거듭 납니다.
- 특징
- 바이너리 프레이밍 계층
- 1.1버전은 줄바꿈으로 구분되는 일반 텍스트로 인코딩
- 2.0은 더 작은 메시지와 프레임으로 분할되며, 각각은 바이너리 형식으로 인코딩
- 스트림, 메시지 및 프레임 교환 방식
- 스트림 : 구성된 연결 내에서 전달되는 바이트의 양방향 흐름
- 모든 통신은 단일 TCP을 통해 수행
- 양방향 스트림의 수는 제한이 없음
- 각 스트림에는 양방향 메시지 전달에 사용되는 고유 식별자, 우선순위 정보가 존재
- 메시지 : 논리적 요청, 응답 메시지에 매핑되는 프레임의 전체 시퀀스
- 각 메시지는 하나의 논리적 HTTP 메시지 이며, 하나 이상의 프레임으로 구성
- 프레임 : HTTP/2에서 통신의 최소 단위이며, 하나의 프레임 헤더가 포함
- 특정 유형의 데이터(HTTP 헤더, 메시지 페이로드 등)를 전달
- 다름 스트림들의 프레임을 interleaving 한 다음, 각 프레임의 헤더에 삽입된 스트리 식별자를 통해 재조립 가능
- 스트림 : 구성된 연결 내에서 전달되는 바이트의 양방향 흐름
- 요청 및 응답 다중화
- HTTP 메시지 프레임 세분화 및 재조립
- 1.1에서 병렬 요청 시 여러 TCP 연결 사용에 대한 동작 해결
- HOL(Head-of-Line) 차단, 기본 TCP 연결의 비효율 사용 해결
- Interleaving
- 여러 요청을 하나도 차단하지 않고 병렬로 interleaving할 수 있음
- 여러 응답을 하나도 차단하지 않고 병렬로 interleaving할 수 있음
- 단일 연결을 사용하여 여러 요청과 응답을 병렬로 전달할 수 있음
- 연결된 파일, 이미지 스프라이트, 도메인 분할과 같은 불필요한 HTTP/1.x 임시 방편을 제거합니다.
- 불필요한 지연 시간을 제거하고 가용 네트워크 용량의 활용도를 개선하여 페이지 로드 시간을 줄입니다.
- HTTP 메시지 프레임 세분화 및 재조립
- 스트림 우선순위 지정
- 각 스트림에 가중치와 종속성 할당
- 스트림의 종속성 및 가중치 조합을 이용하여 클라이언트가 우선순위 지정 트리를 구성
- 트리는 서버에서 CPU, 메모리 및 기타 리소스의 할당하거나 대역폭을 할당
- 각 스트림에 가중치와 종속성 할당
- 출처당 하나의 연결
- 동일한 연결에 대해서 재사용 하기에 전반적인 프로토콜 오버헤드를 대폭 감소
- 또한 더 적은 연결을 하기 때문에 메모리와 처리량이 감소
- 흐름 제어
- 송신기의 데이터가 불필요하거나 처리가 불가능하여 수신기에 부담을 주는 것을 막음
- 흐름 제어는 양방향
- 흐름 제어는 크레딧 기반
- 흐름 제어는 비활성화 할 수 없음
- 흐름 제어는 종단간(End-to-End) 방식이 아닌 홉(Hop-by-Hop)방식
- 송신기의 데이터가 불필요하거나 처리가 불가능하여 수신기에 부담을 주는 것을 막음
- 서버 푸시
- 서버가 단일 클라이언트 요청에 대해 여러 응답이 가능
- 클라이언트가 명시적으로 요청하지 않아도 서버가 추가적인 리소스를 푸시할 수 있음
- 서비스 워커를 사용하여 캐시된 자원을 리턴 받아서 불필요한 네트워크 트래픽을 줄입니다.
- 서버가 단일 클라이언트 요청에 대해 여러 응답이 가능
- 헤더 압축
- HPACK 압축 형식을 사용
- 전송되는 헤더 필드를 정적 huffman 코드로 인코딩
- 공유 압축 컨텍스트를 구성
- 정적/동적 테이블로 구성
- 정적 테이블 : 사양에 정의되며, 모든 연결에 사용될 가능성이 있는 공용 HTTP 헤더 필드를 제공
- 동적 테이블 : 처음에는 비어있으며, 특정 연결에서 교환되는 값에 따라 업데이트
- 정적/동적 테이블로 구성
- HPACK 압축 형식을 사용
- 바이너리 프레이밍 계층
HTTP/3
HTTP/3는 QUIC이라는 프로토콜 위에서 돌아가는 HTTP입니다.
QUIC란?
Quick UDP Internet Connection의 약자로 UDP를 사용하여 인터넷 연결을 하는 프로토콜
TCP 단점
- TCP vs UDP위 그림처럼 TCP는 신뢰성이 높고 느리고, UDP는 신뢰성이 낮고 빠릅니다.
현재 TCP를 사용하고 있는 HTTP/2 보다 빠르게 사용하기 위해서는 TCP를 버리고 UDP를 사용하는 것을 목적으로 하였습니다.
TCP가 느린 이유는 다음과 같습니다.
- 3 Way Handshake 간략히 설명하면 #1~3의 통신을 통해서 정상적으로 연결이 되면 신뢰성이 생겨 이후에 데이터를 주고 받습니다.HTTP/1.1에서는 하나의 TCP 연결에 하나의 요청만 처리하게 되어 있어서 매 요청마다 3 Way handshake를 해줘야 하며, HTTP/2에서는 최소화를 하기 위해 단일 TCP 연결을 유지하면서 여러개의 요청을 처리할 수 있도록 변경되었습니다.
- 하지만, TCP를 버리기 전에는 적어도 1번 이상 3 Way handshake를 해줘야 하기 때문에 속도가 느립니다.
- HOLB(Head of line Blocking)이럴 경우 병목이 발생하는데 이러한 현상을 HOLB라 부릅니다. 이 현상은 HTTP/1, HTTP/2까지 발생하는 문제입니다.
- TCP를 사용한 통신에서는 패킷은 패킷 재조립을 위해서 무조건 정확한 순서대로 처리되어야 합니다. (위에서 시퀀스 번호가 그 예)
그래서 통신 중간에 패킷이 손실되면 완전한 데이터로 다시 조립할 수 없어서 다음 패킷을 처리할 수 없습니다.
따라서, UDP를 사용하여 위 2가지 문제를 해결하여 프로토콜을 개발한 것 입니다.
UDP 사용 이유
- 연결 설정 레이턴시 감소
- TCP + TLS 같은 경우 신뢰성있는 연결과 암호화에 필요한 모든 정보를 교환하고 유효성 검사를 한 후에 데이터 교환
QUIC은 데이터를 바로 전달. 단, 클라이언트가 서버로 첫 요청을 보낼 때는 서버의 세션 키를 모르는 상태이기 때문에 서버의 Connection ID를 사용하여 생성한 특벽한 키를 사용하여 통신을 암호화 합니다. - TCP의 3 way handshake 때문에 연결 시에 레이턴시를 줄이기가 어렵습니다.
- 패킷 손실 감지에 걸리는 시간 단축
참고 : https://www.ietf.org/id/draft-ietf-quic-recovery-29.html#name-relevant-differences-betwee1. Separate Packet Number Spaces 2. Monotonically Increasing Packet Numbers 3. Clearer Loss Epoch 4. No Reneging 5. More ACK Ranges 6. Explicit Correction For Delayed Acknowledgements 7. Probe Timeout Replaces RTO and TLP 8. The Minimum Congestion Window is Two Packets
- 아래는 QUIC에서 속도 향상을 위해서 작업한 방식들입니다.
- 멀티플렉싱 지원
- 위 그림처럼 HTTP/1.1은 하나의 TCP 연결에 하나의 스트림만 사용하기 때문에 HOLB 문제에서 벗어날 수 없습니다.
HTTP/2 같은 경우 하나의 TCP 연결 안에서 여러 개의 스트림을 처리하는 멀티플레싱 기법 도입으로 성능을 끌어올렸습니다.
HTTP/3 또한 HTTP/2와 동일하게 지원합니다. - 멀티플렉싱은 HOLB를 방지하기 위한 기술입니다.
- 클라이언트의 IP가 바뀌어도 연결이 유지됨
- TCP의 경우 소스의 IP 주소와 포트, 연결 대상의 IP 주소와 포트로 연결을 식별하기 때문에 IP가 바뀌면 연결이 끊깁니다.
QUIC은 Connection ID를 사용하여 서버와 연결을 생성합니다. 클라이언트의 IP와는 전혀 무관한 데이터이기 때문에 기존의 연결을 계속 유지할 수 있습니다.
테스트 및 구축 방법
아직 Nginx에서는 preview 상태이며, nginx 1.16.1 소스과 quiche를 받아서 patch 후 compile하여 사용해야합니다.
% curl -O https://nginx.org/download/nginx-1.16.1.tar.gz % tar xvzf nginx-1.16.1.tar.gz % git clone –recursive https://github.com/cloudflare/quiche % cd nginx-1.16.1 % patch -p01 < ../quiche/extras/nginx/nginx-1.16.patch
% ./configure
–prefix=$PWD
–with-http_ssl_module
–with-http_v2_module
–with-http_v3_module
–with-openssl=../quiche/deps/boringssl
–with-quiche=../quiche % make
events {
worker_connections 1024;
}
http {
server {
# Enable QUIC and HTTP/3.
listen 443 quic reuseport;
# Enable HTTP/2 (optional).
listen 443 ssl http2;
ssl_certificate cert.crt;
ssl_certificate_key cert.key;
# Enable all TLS versions (TLSv1.3 is required for QUIC).
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
# Add Alt-Svc header to negotiate HTTP/3.
add_header alt-svc 'h3-23=":443"; ma=86400';
}
}
위와 같이 설정 후 설정한 사이트에 크롬으로 접속하면 protocol에 h3-q050이 보여야 합니다.
아래 이미지는 cloudflare에 접속하여 확인한 화면입니다.
'개발 및 관련 자료 > WEB' 카테고리의 다른 글
[React] React 18 (0) | 2023.02.24 |
---|---|
[React] React 기초 (0) | 2020.02.18 |
React Webpack (babel4 + typescript) 작성하기 (0) | 2019.11.11 |
[es6] const, let (0) | 2019.10.20 |
[es6] destructuring assignment (0) | 2019.10.20 |
Comments