Computer Science

[웹 통신/Protocol/HTTP] 웹 통신과 HTTP에 대해서

Node JS 글을 곧 업로드하기전,  웹 서버에 대한 기본적인 지식을 업로드합니다.

  • 사실, 서버는 "통신"이 기본이기 때문에, 다양한 Computer Network 지식이 필요하지만 항상 "필요한 지식"을 습득하고 바로 적용시키는 인재가 되기 위해서, 필요한 정도까지 , 깊이감있게 해보도록 하겠습니다!

HTTP (HyperText Transfer Protocol)

HTML 문서를 주고 받기위해서 정의된 통신규약입니다. 웹에서 이루어지는 모든 데이터교환의 기초이고, 클라이언트 -서버 모델을 기본으로 합니다. "Client(브라우저) - Server(웹 서버) 사이에서 이루어지는 데이터 교환에 대한 약속" 이라고 생각하면 쉬울것 같습니다.

 

Server - Client 모델

 

Client

 

저는 태어날 때 부터, IE (RIP)나 , FireFox,Chrome과 같은 웹 브라우저가 일상화 되어있었습니다. Client는 "웹 브라우저"라고 이해하고 있습니다. 보통, Client는 "User Side"라고도 이야기하기도 합니다. 왜냐하면, 사용하는 사람이 보는건 Client(웹 브라우저)이기 때문입니다. 주로, 웹서버를 통해서 요청(Request)을 합니다.

 

Server

 

서버는 중앙에서 모든 Client들에게 서로 통신을 하게끔 도와주고 , 중계해주는 역할을 하는 친구입니다. 주로, 데이터를 "전송"해주는 역할을 하고, Client에서 요청(Request)이 들어오면 응답(Response)을 해줍니다. 중요한 비즈니스 로직이나,처리방식, client간의 통신이 잘 이루어지도록 인증,로드밸런싱 등등을 담당합니다. 

즉, HTTP는 이런 서버-클라이언트 구조에서 주고 받는게 HTML인거고, Client 쪽에서는 WebBrowser을 통해서 이 HTML을 해석해서 View로 보는 형태입니다.

HTTP 1.1

HTTP는 1.1 , 2.0 , 3.0까지 발전해온 Protocol입니다. 지금까지도 1.1 , 2.0 ,3.0 모두 혼용해서 쓰고 있습니다. 

  • HTTP 1.1은 기본적으로 TCP를 통해서 서로간의 통신을 시작하고 ,  HTTP Header와 Body를 주고 받으면서 HTML을 전송하게 됩니다. 
  • PipeLining을 이용합니다. 즉, 연속적으로 Request를 보내고, 응답을 기다리는 방식으로 통신을 합니다.

그림으로 보는게 더 이해가 잘 가실 듯합니다.

 

HTTP 1.1은 아주 안정적이고, 확장에도 유연하여서 무려 HTTP2가 발표되기전 까지 10년이 넘는 시간을 사용하였습니다. 훌룡한 Protocol이고, 아직도 사용하고 있습니다. 하지만, 문제점이 있었고 그걸 해결하기 위해서 HTTP2가 발표되었습니다.

HTTP 1.1의 문제점 

HOL Blocking

 

HTTP 1.1은 Pipeline을 적용했기 때문에, TCP/IP Packet에 여러개 담아서 요청(Request),응답(Response)를 보내게 됩니다. 하지만, 이 기술은 구현하기 힘들 뿐만아니라, TCP는 기본적으로 요청받은 순서대로 응답을 합니다. 아래를 생각해보죠.

즉, Client에서 request 1,2,3순서대로 요청했다면, Server측에서 2,3에 대한 요청이 끝났더라도 , 1이 끝날때 까지 기다려야하는 현상이 발생하게 됩니다. (request 1이 엄 -청 큰 이미지고, 2,3은 text라고 생각하면 쉬울까요?) 이런 현상을 HOL Blocking (Head of Line Blocking)이라고 합니다. 앞의 처리가 밀려서 전체가 느려지는 현상.

Header 문제

 

HTTP 1.1은 하나의 TCP/IP Packet에 담아서 , 수많은 HTTP Request를 보내기 때문에 어쩌면 같은 http Header가 중복될 확률이 매우매우 높습니다. (같은 사이트에서 http 통신이 이루어진다면, header정보가 비-슷할거기 때문)

즉, 불필요한 데이터를 주고받는데 네트워크 자원이 많이 소모된다는 단점이 드러나게 됩니다.

 

TCP Connection

 

HTTP 1.1에서는 브라우저와 서버 사이에는 여러 개의 TCP Connection이 형성됩니다.  1개의 패킷에 여러개의 http 통신을 담아서 보내면서 동시에, 여러 개의 TCP connection을 통해서 그 패킷들을 보냅니다. 일반적으로 6개의 Connection을 연다고 하는데, 만약 18개의 Resource가 있다면 3 3 3 3 3 3 이런식으로 보낼 수 있다는 이야기 입니다.

즉, 여러 개의 TCP연결을 설정하고 ,핸드셰이크를 하는등의 네트워크 자원이 소모됩니다. 즉, 전송이 느립니다.

HTTP 2.0

한 개의 TCP 커넥션을 형성해서, Stream 형태로 요청,응답을 주고 받게됩니다. 즉, 데이터들을 Binary(이진) 단위로 바꿔서 마치 한 개의 데이터처럼 보내게 됩니다. 즉, Multiplexing이 일어나게 됩니다.(이걸 보통, Stream형태라고 함)

 

One TCP Connection

 

TCP 연결을 오직 "한 번"한 다음, Client 측에서는 병렬적으로 해당 Packet들을 보내게 됩니다. 연결을 계속 유지한채로,  Stream 형태로 HTTP 요청을 지속적으로 보내게 됩니다.

물론 , HTTP 1.1에서도 keep -Alive 상태로 해당 TCP Connection을 재사용 합니다만, 1개의 Connection에는 기본적으로 1개의 데이터가 왔다갔다 하게됩니다. 하지만, HTTP 2.0은 1개의 Connection에 여러개의 파일들을 얹어서 보내게 됩니다. ( HTTP 1.1은 MultiPlexing을 하지 않습니다.)

Stream을 이용해서 , 처리된것 부터 Response를 받습니다.

 

이때, Response 우선순위를 정해서, 중요한 파일부터 처리되도록 할 수 있습니다. 예를들어, img가 로딩이 되고 css가 로딩이되면 또 브라우저가 repaint를 해야하기 때문에 , img처리가 되기 전에 css를 먼저 처리하도록 합니다. 즉, HOL이 일어나지 않게 되고, Stream형태라  사용자가 느끼기에는 병렬적으로 처리하는 것 처럼 보입니다.

HTTP3.0 (QUIC)

HTTP 2.0은 보안을 위한 TLS와 함께 쓰이게 됩니다.(https) 은행업무나 Email전송과 같은 "인증"이 필요한 경우에는 TLS를 무적권 사용합니다. TCP 통신을 여는과정과 TLS를 여는 과정에서 굉장히 많은 네트워크 자원이 소비되게 됩니다. Tcp Header를 보면 알겠지만, 엄-청 무겁고 , 게다가 TLS과정까지 합치면 ,이건 엄청난 과정을 거치게 되버립니다.

 

그래서, HTTP 3.0에서는 이 두 과정 "key 인증"과 "연결 설정"을 위해서 UDP를 선택하게 되었습니다.

 

최고의 튜닝은 순정이다 - UDP

 

왜 UDP를 선택하게 됬을까라는 의문에는 , 학부생인 저의 좁은 식견으로는 다 대답을 해드릴 순 없지만 몇개의 Reference들을 참고해서 제 나름대로 정리한 것들을 기록하겠습니다.

 

TCP는 마치 잘 준비되어진 라이브러리 입니다. 자바나 ,C++,JS 등을 사용하다보면 라이브러리 중 일부만 import해서 사용하는게 좋습니다. 왜냐하면, 라이브러리를 통째로 import 시키면 매우 무거워지니까요. 하지만, 우리는 이미 TCP의 단점도 알고, 해결해야할 문제점도 압니다. 즉, 필요에 맞게 Custom하기에 좋은 모델은 "데이터 전송 기능"만 "순수하게 가진" UDP가 아니였을까 생각이 됩니다.

 

정리하자면,  기존의 TCP를 수정하기에는 너무 많은 Header들이 이미 자리 잡고 있었습니다. 차라리, UDP를 사용하고 , "UDP에 적절한 모듈을 씌워서 기존의 TCP와 비슷한 역할을 하지만 , 더 빠른 Protocol을 만들자!"가 되었지 않았을까요!

 

TLS를 대체하는 방법 

 

Quic은 연결하는 순간 Connection ID를 생성하고, inital key를 생성하여 연결정보를 같이 던지고 Data를 던지기 시작합니다. key를 어떻게 생성하고, 생성된 key를 상대측에서 어떻게 식별하는지는 자료가 없던데 ,혹시 아시는분은 댓글을 부탁드리겠습니다. 

모바일 환경에서 더 좋은 QUIC

그리고, connect를 할 때, TCP가 아니므로, Connection ID라는 랜덤한 값을 이용하게 되는데 , 이 점 때문에 클라이언트에서는 끊임없는 인터넷 사용이 가능하게 되었습니다. TCP는 와이파이 ->인터넷 , 와이파이 ->셀롤러 등 환경이 바뀌면 연결이 끊어질 수 밖에 없습니다.(IP 기반이기 때문) . 하지만, QUIC은 Connection ID를 생성하고 그걸 갖고 있으므로, 인터넷에 연결만 되어져 있다면, Connection ID를 비교해서 계속 통신을 할 수 있습니다.(모바일 환경에서의 이점)