HTTP 1.1 / HTTP 2.0

손효재·2021년 12월 31일
0

Network

목록 보기
3/6

HTTP/1.1

기본적으로 커넥션 당 하나의 요청과 응답만을 처리한다. 따라서, 동시전송이 불가능하고 요청과 응답이 순차적으로 이루어지게 된다.

  • HTML 문서 내에 포함된 여러개의 리소스 요청 (CSS 파일을 로드하는 link 태그, 이미지 파일을 로드하는 img 태그, 자바스크립트를 로드하는 script 태그 등)이 개별적으로 전송되고 응답 또한 개별적으로 전송된다.

Persistent Connection

HTTP 요청은 TCP 프로토콜을 사용하기 때문에 요청을 전송하기 위해서 3-way handshake가 매 요청마다 발생하게 된다.
→ HTTP/1.1은 매번 TCP 연결을 하는 것이 아니라, 한번 TCP 초기화를 한 이후에 keep-alive라는 옵션으로 연결을 끊지않고 여러개의 파일을 송수신할 수 있게 바뀌었다. 이렇게 요청이 처리된 후에도 커넥션을 유지하는 경우를 Persistent Connection이라고 한다.
* HTTP/1.0에도 keep-alive가 있었지만, HTTP/1.1부터 표준화가 되어 기본옵션으로 설정되었다.

Pipelining

기본적으로 HTTP 요청은 순차적이기 때문에 요청에 대한 응답을 받고 나서야 새로운 요청을 보낸다. 하지만 HTTP/1.1 부터는 응답을 기다리지 않고 요청을 연속적으로 보내는 기능인 Pipelining 스펙이 추가되었다.
하지만, 멱등성이 보장되는 요청(GET, HEAD, PUT, DELETE)에만 적용된다.
→ 응답순서는 보장되어야 하기 때문에, HOL(Head Of Line) Blocking 이 발생한다.

HTTP/1.1의 문제점들

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

여러개의 요청 중 앞선 하나의 응답이 지연될 때, 해당 응답이 완료될 때 까지 다음 요청은 대기상태가 되며 지연된다. 이처럼 특정 요청을 처리할때의 지연으로 다른 요청을 처리하는데 지연이 발생하는 것을 말한다.

RTT (Round Trip Time)

패킷이 목적지에 도달하고 나서 다시 출발지로 돌아오기까지 걸리는 시간이며, 패킷 왕복시간을 의미한다.

하나의 커넥션에 하나의 요청을 처리하므로, 요청 별로 커넥션을 생성한다. 이때마다 3-way handshake가 반복적으로 일어나게 되어 불필요한 RTT가 증가하고, 네트워크 지연을 초래한다.

RTT 증가를 해결하기 위한 방법

  1. 이미지 스플리팅 (Image Spriting)

많은 이미지를 다운로드 받게 될때 요청 횟수를 줄이기 위해, 많은 이미지가 합쳐있는 하나의 큰 이미지를 다운로드 받고, 이를 기반으로 background-image의 좌표값을 이용하여 이미지를 표기하는 방법이다.

  1. 코드압축

개행 문자, 빈칸을 없애서 코드의 크기를 최소화하여 코드 용량을 줄인다.

  1. 이미지 Base64 인코딩

이미지 파일을 64진법으로 이루어진 문자열로 인코딩하는 방법이다.

이렇게하면 서버와의 연결을 열고 이미지에 대해 서버에 HTTP 요청을 할 필요가 없지만, Base64 문자로 변환할 경우 크기가 더 커지는 단점이 있다.

무거운 Header

HTTP/1.1 헤더에는 많은 메타정보들이 저장되며, 압축이 되지 않아 무겁다. 다수의 HTTP 요청이 발생하면, 요청시마다 중복된 헤더값을 전송한다.

HTTP/2

HTTP/1.1의 성능향상에 초점을 맞춰 개선한 것으로, HTTP/1.x 보다 지연시간을 줄이고 응답시간을 더 빠르게 할 수 있다. 커넥션 당 여러개의 요청과 응답, 즉 다중 요청/응답이 가능하다.

멀티 플렉싱 (Multiplexed Streams)

순서에 상관없이 여러개의 스트림을 사용하여 송수신하는 것이다.
HTTP/1.1의 Connection Keep-Alive, Pipelining의 개선이라 보면 된다.

특정 스트림의 패킷이 손실되었다고 하더라도 해당 스트림에만 영향을 미치고 나머지 스트림은 멀쩡하게 동작할 수 있다. 요청 순서에 상관없이 Stream으로 받기 때문에 HOL Bloking이 발생하지 않는다.

요청의 우선순위 처리 (Stream Prioritization)

요청 리소스 간의 의존관계(우선순위)를 정할 수 있다. ex) HTML문서안의 CSS파일과 image파일간의 우선순위

서버 푸시 (Server Push)

클라이언트가 요청하기 전에 서버가 리소스를 클라이언트에게 전송할 수 있다. 리소스를 선제적으로 로드하는 데에 도움을 줄 수 있다.

html에는 css나 js 파일이 포함되기 마련인데 html을 읽으면서 그 안에 들어있던 css 파일을 서버에서 푸시하여 클라이언트에게 먼저 줄 수 있다.

헤더 압축 (Header Compression)

HTTP/2에서는 허프만 코딩 알고리즘을 사용하는 HPACK 압축 형식으로 헤더를 압축하여 전송한다.

* 허프만 코딩 (huffman coding)은 문자열을 문자 단위로 쪼개 빈도수를 세어 빈도가 높은 정보는 적은 비트 수를 사용하여 표현하고, 빈도가 낮은 정보는 비트 수를 많이 사용하여 표현해 전체 데이터의 필요한 비트양을 줄이는 원리이다.

중복된 헤더 값이 존재하는 경우, static/Dynamic Header Table 개념을 사용하여 중복 헤더를 검출하고, 중복된 헤더정보는 index 값만 전송하고 중복되지 않은 값은 허프만 인코딩 기법으로 인코딩하여 전송한다.

HTTP 1.1 vs HTTP 2

HTTP/1.1 에서 keep-alive 옵션으로 1번의 3-way handshake로 TCP 연결 후 데이터를 여러개 보내는 것과 HTTP/2 에서 한 커넥션으로 여러개의 요청과 응답을 보내는 것은 어떤 차이가 있는가?

HTTP 1.1에서 keep alive 옵션으로 커넥션을 유지시켜도 응답은 순서대로 와야하지만, HTTP 2에서 스트림을 사용한 통신은 응답도 순서가 상관없다.

HTTP/2 에서 커넥션은 언제까지 keep-alive되어있는가?

HTTP/2 연결은 지속적이다. 최상의 성능을 위해 클라이언트는 서버와 추가 통신이 필요하지 않다고 판단될 때까지 (예: 사용자가 특정 웹 페이지에서 다른 곳으로 이동하는 경우) 또는 서버가 연결을 닫을 때까지 연결을 닫지 않을 것이다.

서버는 가능한 한 오랫동안 열린 연결을 유지하도록 권장되지만 필요한 경우 연결을 종료할 수 있다.

endpoint가 전송 계층 TCP 연결을 닫도록 선택하면 종료 끝점은 먼저 GOAWAY 프레임을 보내서 두 endpoint가 이전에 보낸 프레임이 처리되었는지 여부를 안정적으로 결정하고 필요한 나머지 작업을 정상적으로 완료하거나 종료할 수 있도록 해야 한다.

따라서 두 endpoint 모두 GOWAY 프레임 을 전송하여 정상적으로 연결을 닫을 수 있다.
nginx 및 Apache 를 사용하면 유휴 HTTP/2 연결이 종료되는 시간 제한을 구성할 수 있다. (nginx 기본값은 3분, Apache는 5초)

0개의 댓글