HTTP/2.0란?
글을 쓰게 된 이유
HTTP 관련 책에서 HTTP/1.1은 현재의 HTTP 버전이다.
라는 문장을 읽고 맞는 정보인건가 싶어서 확인해보니 HTTP/2
와 HTTP/3
을 쓰고 있다..?!
HTTP/2.0은 HTTP/1.1이랑 뭐가 다른지 궁금해져서 찾아보기로 했다.
HTTP/2.0의 등장 배경
HTTP/1.1은 구현의 단순성과 접근성에 초점을 두고 있다보니 성능이 좋지 않다.
커넥션 하나에 요청 하나를 보내고 응답 하나만 받을 수 있고 응답을 받아야만 그다음 요청을 보낼 수 있기 때문에 지연이 발생한다.
이러한 문제를 해결하기 위해 병렬 커넥션과 파이프라인 커넥션이 도입되었지만 성능 개선에 대한 근본적인 해결책이 되지 못했다.
병렬 커넥션
여러 개의 TCP 커넥션을 통한 동시 요청을 보낼 수 있다.
클라이언트가 다수의 커넥션을 하게 되면 서버에 부하게 생겨 성능이 떨어지는 문제점이 있다. 예를 들어 100명의 사용자가 각각 100개의 커넥션을 맺으면 서버는 10,000개의 커넥션을 떠안게 된다.
파이프라인 커넥션
커넥션이 지속 커넥션인지 확인되면 요청을 연속으로 보낼 수 있다. HTTP/1.1에서는 별도 설정을 하지 않는 한, 모든 커넥션은 지속 커넥션이다.
먼저 보냈던 요청 작업에 문제가 발생하면 이후에 들어온 요청 작업이 끝나도 응답을 못보내는 현상이 생긴다. 이를 Head-of-line blocking이라고 한다.
결론은 성능 개선을 위해 HTTP/2.0이 등장했다.
HTTP/2.0이란?
HTTP/1.1의 성능 개선을 위해 몇가지 기능을 추가한 프로토콜이다.
프레임
HTTP/2.0에서 모든 메시지는 프레임에 담겨 전송된다. 총 10가지 프레임이 존재한다.
HTTP/1.1과는 다르게 HTTP/2.0은 바이너리로 데이터를 인코딩하고 작은 단위로 나눠서 전송할 수 있다.
스트림
스트림은 클라이언트와 서버 사이에서 교환되는 프레임들의 독립된 양방향 시퀀스다.
한 쌍의 요청과 응답은 하나의 스트림을 통해 이루어진다. 클라이언트는 새 스트림을 만들고 그 스트림을 통해 요청을 보낸다. 요청을 받은 서버는 그 스트림으로 응답을 보낸다.
스트림은 우선순위를 가질 수 있기 때문에 중요한 리소스를 요청하는 스트림에게 높은 우선순위를 부여할 수 있다.
멀티플렉싱
하나의 커넥션 위에 여러 개의 스트림이 동시에 만들어질 수 있이며 여러 개의 요청과 응답을 동시에 처리할 수 있다.
각 스트림내의 응답과 요청의 순서는 보장되어야 하지만 스트림 간의 처리 순서는 중요하지 않다.
이를 통해 HTTP/1.1의 파이프라인 커넥션을 개선하였다.
헤더 압축
HTTP/1.1에서 헤더는 아무런 압축 없이 그대로 전송되었으며 중복값이 존재했다.
HTTP/2.0에서는 HPACK이라는 헤더 압축 방법으로 헤더를 압축한 뒤 전송한다.
정적/동적 헤더 테이블을 통해 중복을 검출하고 테이블 인덱스값만 전송함으로써 중복값을 재전송하지 않는다.
서버 푸시
서버가 하나의 요청에 대해 응답으로 여러 개의 리소스를 보낼 수 있도록 해준다.
이 기능은 서버가 클라이언트에서 어떤 리소스를 요구할 것인지 미리 알 수 있는 상황에서 유용하다.
예를 들어, HTML 파일에 링크되어 있는 이미지, CSS 파일, JS 파일 등의 리소스.
HTTP/2.0의 문제
HTTP/2.0은 여전히 TCP를 이용하기 때문에 지연이 발생한다.
TCP는 패킷이 유실되거나 오류가 있을때 재전송한다. 이 과정에서 결국 HOLB 문제가 발생한다.
…그리하여 HTTP/3.0이 등장하게 된다.