우클릭방지

글 목록

2021년 2월 25일 목요일

[HTTP]HOL 블로킹 (Head of Line Blocking)

HTTP 통신에서 성능에 큰 영향을 주는 HOL(Head Of Line) Blocking 에 대해서 정리해 본다. 

웹의 보편화와 함께 HTTP 프로토콜은 성능 측면, 특히 지연속도(Latency) 를 줄이려는 노력을 끊임없이 하고 있다. 

HTTP 1.0 에서 HTTP 1.1 로 발전함에 따라 추가된 다음의 기능들이 크게 대표적이라 할 수 있겠다. 

  • Persistent
  • Pipelining
이 밖에도 HTTP 캐시(Cache) 에 대한 헤더들도 HTTP 1.1에 많이 추가되거나 발전되었는데, HTTP 캐시 역시 궁극적으로는 네트워크를 통한 컨텐츠 요청 수를 줄여 응답 속도를 개선하려는 것이 가장 큰 이유이다. 

이런 많은 노력에도 불구하고 웹 지연 속도의 핵심적인 원인인 HOL 블로킹은 HTTP 1.1 에서 해결하지 못했다.  아니, 어찌 보면 HTTP 1.1 에서 생긴 문제라고 할 수 있겠다. 

HTTP/2 가 되서야 Multiplexing 기능에 의해 HTTP 프로토콜단의 HOL Blocking은 해소가 되게 된다. 
HTTP/2 에 대해서는 다음 포스팅에 자세히 다루도록 하겠다. 

그럼 HTTP 통신에서 Latency 지연을 유발하는 HOL Blocking 에 대해 정리해 보자. 
HTTP 1.1 에서 Persistent + Pipelining 을 통해 다음과 같은 통신이 가능해졌다. 


Pipelining 을 통해 3개의 요청을 한번에 보내게 되면 왕복 시간(Round-Trip time)을 줄일 수 있어 응답 지연(Latency) 에 매우 좋은 효과를 기대 할 수 있다. 

하지만 만약 첫번째 요청의 처리가 서버에서 오래 걸릴 경우 두번째, 세번째의 응답이 같이 지연되게 된다. 이게 HOL Blocking 이다. 




예로 들면.. 

요리를 하는 누군가에게 다음 3가지를 동시에 주문한다고 하자. 
  • 1번 요청 : 삼계탕
  • 2번 요청 : 양파 1개
  • 3번 요청 : 당근 1개
요청을 받은 사람은 당근과 양파는 쉽게 내줄 수 있음에도 불구하고 첫번째로 들어온 주문인 삼계탕을 다 만들기 전까지 내 줄수 없게 되는데.. 이게 HOL Blocking 인 셈이다. 

그럼 다음과 같은 궁금증이 생기지 않는가? 

"왜 순서대로 응답을 줘야만 하지? 먼저 처리할 수 있는 것들은 먼저 응답을 주면 안되나?"

이에 대한 답은 RFC 문서를 참고하면 해소된다. 

웹 서버는 Pipelining 을 통해 한번에 여러 개의 요청을 받을 수 있으나, 응답 순서는 요청 순에 따라야 함이 HTTP 프로토콜의 규칙(Rule)인 셈이기 때문이다. 

RFC 2616의 8번째 섹션에서 다음의 내용을 다루고 있으니 참고하면 좋겠다. 

8.1.2.2 Pipelining

A client that supports persistent connections MAY "pipeline" its requests (i.e., send multiple requests without waiting for each response). A server MUST send its responses to those requests in the same order that the requests were received.

-> 서버는 반드시 응답을 요청 순서(request in the same order)에 맞추어 전달해야 한다.

Clients which assume persistent connections and pipeline immediately after connection establishment SHOULD be prepared to retry their connection if the first pipelined attempt fails. If a client does such a retry, it MUST NOT pipeline before it knows the connection is persistent. Clients MUST also be prepared to resend their requests if the server closes the connection before sending all of the corresponding responses.

Clients SHOULD NOT pipeline requests using non-idempotent methods or non-idempotent sequences of methods (see section 9.1.2). Otherwise, a premature termination of the transport connection could lead to indeterminate results. A client wishing to send a non-idempotent request SHOULD wait to send that request until it has received the response status for the previous request.


* RFC 2616 의 8번째 섹션 전문 : [여기] 를 클릭하여 확인

-끝-



댓글 없음:

댓글 쓰기