2019년 5월 17일 금요일

[Webpack 공부 #1] Http1.1 and Http2

새로 취직하게 된 직장에서는 어렴풋이 모든것을 처음부터 시작해야하는것이 아닌가 하는 판단이 들기 시작하고 있습니다.
코드관리, 서버, 배포, 모든 환경을 스스로 정의해야할지도 모른다는 생각이 점차 들기 시작하여, 저는 개발환경 구축부터 서비스를 위한 환경구축에 대한 정보 탐색을 시작했습니다.

당장 머릿속에 떠돌던 몇가지 자동화 혹은 개발환경의 힌트들이 면접중에 떠올랐습니다.

GitLab Jira DevOps Docker Jenkins..

왜냐하면 저에게 '환경 구축'이라는 단어들에 대해서 매우 생소하고 무지렁이인 상태였기 때문입니다.

무지렁이가 할수있는것은 리서칭 이지요!

우선 요청도 있고 해서 먼저 리서칭 한것은


Webpack 입니다.

웹팩이란 js 모듈이나, 기타 리소스들을 하나로 묶는 모듈 번들러 입니다. 그럼 왜 js나 리소스들을 하나로 묶는가에 대해 알아보아야 합니다. 그것을 알기 위해서는 HTTP1.1에 대해서 알아봐야 합니다.

HTTP 1.1 vs HTTP 2

기본적인 웹 프로토콜에서는 1요청당 1응답만을 돌려줍니다. 이 말은 하나의 웹 페이지에 필요한 리소스 파일들이 아래와 같다고 하면 [ index.html | default.css | foo.js | favicon.jpg | index.png ] 우리는 HTTP 요청과 응답 handshake 를 5번 해야 모든 윂페이지 로딩이 정상적으로 끝나게 됩니다. 5번의 지연시간이 소요되는것 입니다. HTTP 1.1의 전송방식에 문제점은 몇가지가 있는데,
1. HOL Blocking ( Head of Line Blocking)
동일한 네트워크 큐에 있는 패킷들이 Head부분의 패킷에 의해 지연되는 형상을 야기하는데,
웹 환경에서 HOL Blocking은 두가지가 있습니다.
HTTP HOL Blocking
TCP HOL Blocking
HTTP1.1 에서 앞서 언급된 여러개의 리소스를 모두 받기 위해서는 하나의 파일당 하나의 요청을 주고받는 행위를 없에기 위해 pipelining이 나왔습니다. 이 기술은 단 한번의 커넥션을 통해 TCP socket을 연결하는 방식입니다. 소켓이 연결이 되면, 해당 소캣을 통해 리소스들을 하나하나 순차적으로 받는 방식입니다. 이 말은 HTTP1.1에서는 전송방식이 반드시 동기화 형식으로 차례로 받을수 밖에 없다는 문제점을 보여줍니다. 하지만 이방식 역시 socket 통신을 통해 이루어지며, 그러는 와중에 리소스 다운로드에 지연시간이 생길 수 있습니다. 이런 경우, 다음 리소스들은 현재 받고있는 리소스의 다운로드가 완료 될 때 까지 팬딩상태에 머무르게 되며, 이를 우리는 HTTP HOL Blocking 이라고 부릅니다. TCP의 특성상 보낸 데이터가 올바르게 전송되었는지 확인한 후, 실패시 다시 보낼 수 있게 설계되어있는데( 3way hand shacking) 이런 경우가 발생할시, TCP는 전송받은 패킷의 순서를 관리하기 위해, 재전송을 받을때 까지 다음 순서의 패킷을 받지 않게 되며, 이런경우 TCP HOL Blocking이 걸린 상태라고 부를 수 있습니다.

2. 높아지는 RTT(Round Trip Time) 위에서 언급되다싶이, HTTP1.1은 동시에 하나의 connection(물론 세팅을 통해 늘릴수 있다고도 한다)을, 동기적으로 처리하기 때문에, TCP구조인 HTTP의 특성상 3way-handshacking을 하나의 리소스를 받을때 마다 이루어지기 때문에 RTT가 증가됩니다.

3. Header의 비대화 HTTP 1.1 이 되어가며 Header에 입력되는 메타데이터들의 양이 늘어나게 됩니다.그리고 모든 connection을 통한 통신에서는 Header가 반드시 포함됩니다. 특정 경우에 따라 완벽히 동일한 Header가 몇번이고 반복적으로 전송되기도 할것 입니다( 하나의 동일한 높은 용량의 데이터인 경우 페킷을 나누어 전송할 것 이며, 이때 헤더는 페킷 순서와 끝 유무 정도를 재외하면 동일할 것 입니다)


이러한 여러가지 문제점들이 있었고, 솔루션 또한 여러가지 존재하게 되었었습니다.
하지만 근본적인 솔루션들은 아니었으며, HTTP2 가 이러한 문제들을 해결하기 위해 나타났습니다...
그리고 HTTP2는 1.1과 동일한 형태를 유지하되 속도적인 측면을 개선하기 위해 개발되었으므로, 기존 명세와는 큰 차이는 없습니다. 추가는 있겠지만..

그리고 HTTP2에서 소개하는 기술은 아래와 같습니다.
Multiplexed Streams
클라이언트는 하나의 connection에서 이제 여러개의 메세지들을 받을 수 있습니다. 그리고 이제 순서를 따지지 않으며, stream으로 받게 됩니다.
Stream Prioritization
순서를 따지지 않고 데이터들을 받을수 있다는것은, 보여줄 내용을 순서에 맞게 보낼 수 없다는 의미이기도 합니다. 예를들어 js파일을 먼저 받고싶지만, 순서를 따지지 않게되기 때문에, 어느 타이밍에 js파일을 받는지 알 수 없게 됩니다. 그러한 이유로 각각의 리소스파일에 우선순위인 가중치 를 부과 할 수 있으며, 이를통해 무엇을 우선적으로 받을 수 있습니다.
Server Push
이제 클라이언트의 요청이 있지 않아도 서버는 임의로 데이터를 전달 할 수 있습니다. 기존의 1.1 에서는 클라이언트는 html을 먼저 받은뒤, 이후에 추가적으로 무슨 리소스가 필요한지 파악을 할 수 있었고, 요청을 보낼 수 있었습니다. 하지만 Server Push를 이용하여, 클라이언트가 첫번째 요청을 하게되면, 서버측에서 추가적으로 필요한 리소스들을 찾아내어 클라이언트의 추가 요청없이 임의로 전송을 하는 방식입니다. 이렇게 함으로써 connection 추가 요청 수를 줄이는 방법으로 성능향상을 꽤합니다.
Header Compression
무겁고 중복적으로 전송되는 Header 다이어트를 목적으로, Header Table과 Huffman Encoding 기법을 사용하게 됩니다. Header Table는 처음 전송받은 Header를 특별한 Table에 저장 해 두며 또다시 헤더를 요청받게 되면, 기존에 저장된 헤더 table과 diff를 때려서, 다른 부분만 명세하여 전송됩니다. 이렇게 함으로써 중복되는 header 데이터 전송 낭비를 해결했으며, 상당한 수준의 로드타임 개선을 이루었습니다.


댓글 없음:

댓글 쓰기