HTTP 요청/응답 과정과 커넥션, 최적화를 위한 HTTP2의 특징

junamee·2021년 7월 6일
0

네트워크

목록 보기
1/4
post-thumbnail

HTTP

웹페이지를 보기 위한 프로토콜 HTTP
애플리케이션 계층은 클라이언트에서 실제 체감하는 서비스를 제공하는 역할을 한다.
웹 서버와 브라우저간 데이터를 요청하는 URL과 응답결과로 전달되는 웹 페이지 데이터가 오간다.
(이 때 목적지 PC프로그램에 데이터가 제대로 전달되도록 포트번호정보를 헤더에 붙이거나 떼어내는 역할을 트랜스포트 계층에서 담당하고 있다.)

HTTP 요청과 응답과정 (간략)

  1. 웹 페이지 URL 요청(HTTP요청) ->
  2. 웹페이지 HTML데이터 응답(HTTP응답) ->
  3. HTML데이터 해석하여 웹페이지 형태로 표시->
  4. 이 때 HTML파일에는 CSS, JS, JPEG 등 웹화면을 그리기 위한 다른 파일들도 존재하는데 이 파일들을 받기 위해 새로운 요청을 보낸다.->
  5. 응답으로 받은 기타 파일들을 조합하여 웹 페이지에 표시한다.
    (웹페이지가 아닌 웹서비스에 대한 요청을 보낼 때도 동일하다, 다만 웹페이지요청에 대한 응답은 미리 만들어 둔 정적html파일 데이터였는데, 서비스 요청시에는 요청이 들어오면 그때 HTML데이터를 동적으로 생성해(HTML형식으로) 응답한다.)

* 위는 웹페이지 전체를 다시 그려 갱신하는 방식임 (웹서버 - 웹 브라우저)
최근에는 AJAX기술을 사용해 자바스크립트로 작성된 프로그램이 웹서버와 통신하며 응답받은 내용 중 갱신이 필요한 부분에만 응답내용을 반영한다. 전체페이지를 조회하지 않아 자연스러운 서비스가 가능하다. (EX.검색창 연관검색어 보여주기:입력마다 화면전체를 렌더링하지 않게된다.)

HTTP 이슈

무거운 헤더 구조

헤더정보에 캐싱정보를 포함한 다양한 내용이 포함되어있는데 동일한 내용의 헤더를
요청때마다 동일하게 보내는 것이 문제이다.

무상태 프로토콜(stateless)

통신 시 정보를 한 번씩 주고받고 바로 끊어 상태 정보를 저장하지 않는다.
웹 서비스에서는 상태 정보 유지를 위한 별도의 처리가 필요하다.
ex) 동일 사용자의 요청여부 판단 어려움
:여러 단계의 흐름이 이어지는 요청(ex_쇼핑몰 상품구매~결제)에 대해 동일 사용자임을 인식해야함
(=> 쿠키가 사용됨)

단기 커넥션

  • HOL Blocking
  • RTT 증가

short-lived connection: 1 Request 1 Response per 1 Connection

  • HTTP/1.0에서 사용된 기본 모델
    (Connection 헤더가 존재하지 않거나, 그것의 값이 close로 설정된 경우임, 사용할 필요 x)
  • 하나의 요청에 대한 응답을 받고 나서야 다음 요청을 실시
    네트워크 지연과 대역폭 제한에 걸려 다음 요청을 보내는 데까지 상당한 딜레이가 발생할 수 있다.
  • 매번 새로운 연결로 성능 저하 ('요청-응답-종료'의 반복)
    : 커넥션을 담당하는 전송프로토콜로 TCP를 사용하고 있으며 TCP는 전송 속도보다 신뢰성을 더 중요시 하는 프로토콜(핸드쉐이크-연결자체에 상당한 시간이 걸림)이어서 적지 않은 자원을 소비하게 된다. 또한 TCP커넥션은 지속적으로 연결되었을 때 효율적으로 작동하는데 이런 특성을 사용하지 못하고 새로운 연결을 요청하면서 최적의 상태보다 저하된 성능을 보인다.
  • 서버 부하 비용

Persistent Connection: keep-alive Connection

위의 문제점을 해결하기 위해 추가된 연결 방법
지정시간 동안 커넥션을 닫지 않고 유지해 새 커넥션을 연결하는데 필요한 시간을 단축한다. 또한 커넥션을 지속적으로 사용하면서 성능향상을 기대할 수 있다. (일정시간: Keep-Alive 헤더를 사용해 연결시간을 설정할 수 있음)

단점으로는 요청이 없는 상태에서도 서버리소스를 소비하게 된다.

Pipelining

영속적인 커넥션 상태에서 요청을 응답을 기다리지 않고 연속적으로 보낸다. 사전 요청에대한 지연을 회피해 왕복시간(Roud-Trip time)을 줄일수 있다. 하지만 첫번째 요청의 처리가 서버에서 오래 걸리는 경우, 그 다음 요청의 응답 역시 함께 지연된다. Head of Line Blocking (HOL)이라고 한다. (HTTP프로토콜에 따라 서버는 요청 순서에 맞추어 응답을 전달한다.)

정리

커넥션관리가 http 성능향상에 큰 영향을 끼친다.
요청 유휴 상태가 길지 않다면, 단기 커넥션보다 영속적 커넥션이 좋은 성능을 보장하고 유휴상태에 대한 아쉬운 점을 고려하기 위해 파이프라이닝이 고안되었으나 HOL문제 등의 단점을 HTTP2에서 보안하게 되었다.


HTTP2

HTTP1의 성능을 집중적으로 개선한 프로토콜

  • HTTP/1의 최소요청단위 : request message (line + header)
  • HTTP/2의 최소요청단위 : 프레임
HTTP/2는 프레임이라는 최소 단위로 요청과 응답을 전송합니다.
HTTP/2 프레임은 요청과 응답 뿐만 아니라 상태 관리, 제어, 오류 정보 등의 다양한 정보를 전송할 수 있는 단위입니다.

각 프레임은 헤더와 데이터로 구성되며, 헤더는 프레임의 종류, 우선 순위, 스트림 식별자 등의 정보를 포함하고, 
데이터는 실제 정보를 전송하는 부분입니다.

Header Compression

무거운 헤더정보를 요청때마다 동일하게 보내야하는 것이 HTTP1의 단점이었는데 HTTP2는 중복된 헤더가 들어오면 HPACK(Hash Table + Huffman Encoding)이라는 압축방식을 통해 헤더의 크기를 압축한다. 결과적으로, 중복된 헤더는 HashTable개념을 바탕으로 인덱스값만 전송하고 중복되지 않은 헤더는 Huffman Encoding기법으로 인코딩하여 전송한다.

HTTP 메시지 전송 방식의 변화

: 바이너리 형태의 프레임으로 나누어 요청을 보냄(프레임_HTTP2요청 최소 단위)
=> 파싱,전송속도가 향상, 텍스트보다 오류 줄음

요청응답 Multiplexing *

:HOL 해결
가장 최소단위의 프레임으로 변경되어 사실상 요청 순서라는게 사라지고 인터리빙(끼어듬)이 가능하게 되어 프레임이 재조합되 메시지가 만들어진다.
이러한 메시지들이 모여 양방향의 스트림이 된다.
즉, 하나의 스트림에 여러 메시지(요청/응답 단위)가 있어 동시에 여러 메시지를 처리할 수 있게 되고 응답프레임들은 요청 순서에 상관없이 만들어진 순서대로 클라이언트에 전달되게 된다.

Stream Prioritization

:리소스간 우선 순위 설정 가능
예로 빠른 브라우저 렌더링을 위해 JS파일보다 CSS를 먼저 받도록 할 수 있다.

Server push

:필요한 요청을 서버가 알아서 판단하고 요청 전에 리소스를 보내준다.
보내준 리소스에 대해서는 클라이언트는 요청을 보내지 않게 된다.

ex) html데이터에 필요한 css, js파일을 요청 전에 보내준다.
HTTP1에서는 HTML/CSS/JS를 모두 별개의 요청을 보냈었다.

Improved Security

HTTP/2 includes improved encryption and authentication features, making it more secure than HTTP/1.1.


정리

크게 HTTP1과 HTTP2를 비교했을 때,
HTTP2는 HTTP1의 약점을 보완했다고 볼 수 있다.
보안이슈도 보완되었겠지만 크게는 전송속도 성능이 향상된 것을 확인할 수 있다.

  • 헤더 압축
  • 요청 횟수 감소 (ServerPush)
  • 요청 지연 문제 해결 (Multiplexing)

profile
아티클리스트 - bit.ly/3wjIlZJ

1개의 댓글

comment-user-thumbnail
2023년 10월 17일

좋은 글 잘 읽었습니다. 이 글에 추가적으로 덧붙이고 싶은 말이 있습니다. Http1에서 발생했던 HOL Blocking 문제는 request를 보낸 "순서"대로 response를 받는게 문제입니다. 더 근본적으로 생각해보면 각 request와 각 response를 구분할 수 있는 식별자가 없다는겁니다. 이 문제를 해결하기 위해서 google에서 식별자가 존재하는 stream이라는 개념을 추가시켰죠. 이 stream의 동작 과정은 다음과 같습니다.
1. 클라이언트가 새로운 요청을 생성하고 이를 여러 개의 프레임으로 나눕니다. 각 프레임은 동일한 스트림 ID를 가지며, 이 ID는 클라이언트에 의해 자동으로 생성됩니다.
2. 클라이언트는 이들 프레임을 서버에 전송합니다. 하나의 TCP 연결을 통해 여러 스트림의 프레임들이 동시에 전송될 수 있습니다.
3. 서버가 프레임을 받으면 스트림 ID를 확인하여 어떤 요청에 해당하는지 판단합니다.
4. 서버는 해당 요청을 처리한 후, 응답 메시지를 다시 여러 개의 프레임으로 나눕니다. 이들 응답 프레임도 원래 요청과 동일한 스트림 ID를 가집니다.
5. 서버는 이응답 프레임들을 클라이언트에게 전송합니다.
6. 클라이언트가 응답 프레임을 받으면 스트림 ID를 확인하여 어떤 요청의 응답인지 판단하고, 필요한 조치(예: 메시지 재조합)를 취합니다.

좋은 하루 보내세요

답글 달기