HTTP
HyperText Transfer Protocol이라는 이름에서 알 수 있듯, protocol 즉 전송규약입니다.
이 규약을 통해서 ①누구를 위한 ②어떤 데이터를 주고받을지는 정하기 나름입니다.
일반적으로 웹 브라우저에 http:// 을 입력하기 때문에
HTTP는 웹 페이지를 로딩하기 위한 것이라고 생각할 수도 있지만,
HTTP는 컴퓨터 시스템간 기계적 정보를 주고받는데 광범위하게 이용됩니다.
이것이 web API 입니다.
- 이때 응답으로 전송되는 것은 HTML 문서가 아닙니다.(HTML은 대개 사람을 위한 것입니다.)
- 컴퓨터 간 통신에서는 HTTP 응답 코드가 가장 중요하고 응답 코드에 따라 응답의 Body를 해석합니다.
HTTP는 TCP 위에서 동작하는 Protocol입니다.
따라서 TCP가 제공하는 "전송 보장"을 마찬가지로 제공합니다.
또한 TCP가 겪는 오락가락하는 throughput을 동일하게 겪습니다.
따라서 반응성보다는 안정성이 중요한 응용에 적합합니다.
HTTP는 Request-Response 방식의 protocol입니다.
Request를 먼저 보내야만 그다음에 response를 보낼 수 있습니다.
따라서 클라이언트-서버 구조에서 "서버가 아무 때나 데이터를 전송하는 것"이 안됩니다.
Q) 이걸 가능하게 하려면 어떻게 해야 하나요?
A) 클라이언트가 polling을 해야 합니다. 즉, request 할 것이 없음에도 "나한테 보낼 데이터 있어?" 목적의 비어 있는 request를 주기적으로 전송해야 합니다.
Q) 이런 polling의 문제점은?
A) ①서버 과부하 ②불필요한 네트워크 트래픽
따라서 서버가 아무 때나 데이터를 보내야 되는 응용에 적합하지 않습니다.
HTTP 구조 - Request
Query String
Request line의 URL 중 일부입니다.
요청의 parameter를 정하는 역할을 하며
Key-value 구조이고 각 Key-value는 &로 연결합니다.
예: q=test&lang=en →q=test와 lang=en의 결합
HTTP 구조 - Response
HTTP 헤더 중 Content-Type
- Body 영역의 데이터 타입과 문자 인코딩 방식을 결정합니다.
- 전송되는 데이터에 따라 다른 값이 사용됩니다.
예: HTML 문서 → Content-Type: text/html; charset=utf-8
예: HTML form → Content-Type: multipart/form-data; boundary=something - RESTful API에서는 많은 경우 다음 둘 중 하나가 사용됩니다.
- application/json; charset=utf-8
- application/x-www-form-urlencoded; charset=UTF-8
HTTP/1.1
HTTP/1.0에서는 하나의 request-response를 처리하면 TCP 연결을 종료합니다. 그리고 다음 request-response를 처리하기 위해서 다른 TCP 연결을 맺습니다.
Q) 이 방식의 문제점은?
A) TCP 연결은 3-way handshaking이라는 방식을 따릅니다.
즉, 단방향으로 3회 왔다 갔다 하면서 많은 지연을 유발합니다.
따라서 모든 request-response가 이 지연을 겪게 됨을 의미합니다.
웹 페이지에는 많은 수의 HTML, CSS, JavaScript, 그림 파일이 포함되므로 이는 웹페이지가 뜨는데도 굉장히 큰 지연이 발생함을 의미합니다. 또한 매번 새로운 소켓이 생기므로 서버 측 OS에도 과부하가 생깁니다.
Persistent Connection (지속성)
HTTP/1.1부터는 Persistent Connection이라는 방식을 쓸 수 있습니다.
이는 request-response가 처리된 후에도 TCP 연결을 끊지 않고
다음 request-response가 발생할 때 이 연결을 재활용함을 의미합니다.
이 기능을 쓰기 위해서는
HTTP 헤더에 Connection: Keep-Alive라는 항목을 추가하면 됩니다.
Pipelining
하나의 request가 처리된 후, 즉 response가 발생한 뒤에야 또 다른 request를 전송할 수 있습니다.
이는 웹 페이지 로딩처럼 여러 request를 해야 되는 경우 지연이 높아집니다.
이 때문에 HTTP/1.1에서는 response를 아직 받지 못했어도 연속으로 request를 보낼 수 있습니다.
- 단, 이 경우도 request는 순서대로 처리되어야 되므로 response를 누락할 수는 없습니다.
- 그 때문에 처리에 오래 걸리는 request이후의 request들은 여전히 병목이 발생합니다.
HTTP/2.0
Multiplexed Streams
HTTP/2.0에서는 하나의 연결 안에 여러 흐름이 존재하는 걸로 처리하는 멀티플레스 스트림이라는 것을 지원합니다.
즉 여러 스트림이 있는 것을 묶어서 처리한다는 뜻입니다.
프로그래밍 안에 멀티스레드가 있는 것처럼 연결 하나 안에 스트림이라는 것이 여러 개 있다고 가정하고
그 스트림 안에 스트림을 여러 개를 묶어서 처리할 수 있게 되었습니다.
HTTP/1.1에서는 10개의 요청을 보낼 때 10개를 쭉 보내다가 중간에 병목이 있으면 나머지가 기다려야 하지만
HTTP/2.0에서는 스트림을 10개로 만들면 요청 10개는 모두 독립이 되는 것입니다.
그래서 오래 걸리는 request는 오래 걸리고 빠른 request는 빨리 처리가 가능해졌습니다.
연결 한 개 안에 클라이언트가 어떤 스트림에 요청을 보내는지 구분할 수 있는 것입니다.
Server Push
HTTP/1.1에서는 연관되어 있는 데이터라고 하더라도
클라이언트가 일일이 request를 보내야 했습니다.
예: HTML 페이지 안에 같이 쓰이는 CSS, JavaScript 파일들을 각각 별도로 request를 만들어서 요청해야 합니다.
HTML/2.0의 Server Push는 클라이언트가 HTML만 요청해도 연관되어 있는 데이터들을 다 밀어줍니다.
비록 request를 pipelining 할 수 있다고 하더라도
클라이언트가 일일이 request 하지 않고
서버가 알아서 전송을 해주는 것이 latency를 더 줄일 수 있을 것입니다.
이를 "Server Push"라고 하고 HTTP/2.0에서 지원됩니다.
2023년 12월 12일 현재 단 35.8%의 웹사이트들이 HTTP/2.0을 사용하고 있습니다.
출처: https://w3techs.com/technologies/details/ce-http2
즉, 현재까지도 HTTP/1.1이 가장 많이 쓰이고 있습니다.
'CS' 카테고리의 다른 글
[OS] C++의 Thread (1) | 2023.12.12 |
---|---|
[OS] Multi-processing, Multi-threading (0) | 2023.12.10 |
[OS] Multi-Programming, Multi-Tasking (0) | 2023.12.10 |
[OS] CPU utilization, CPU load (1) | 2023.12.10 |
[Network] Socket Options, I/O Multiplexing과 Non-blocking I/O (1) | 2023.10.23 |