HTTP
HTTP(Hyper Text Transfer Protocol)은 HTML 문서와 같은 리소스들을 가져올 수 있도록 해주는 프로토콜 입니다.
웹 브라우저와 웹 서버간의 통신을 위해 디자인 되었습니다.
HTTP 요청이 발생하면 브라우저는 HTTP 요청 메시지를 생성하고 TCP/IP 프로토콜을 이용하여 웹 서버에 요청을 전달합니다.
이후 브라우저는 웹 서버로부터 HTTP 응답을 전달 받습니다.
HTTP요청 메시지는
크게 startline, 헤더와 바디로 구성되고
startline에는 메소드, 경로, 프로토콜의 버전이 추가됩니다.
헤더에는 요청에 설정한 HTTP 헤더들이 들어갑니다.
바디에는 POST 요청일 경우에 추가되고 다른 메서드의 경우에는 추가되지 않습니다.
HTTP 응답 메시지에는
크게 startline, 헤더와 바디로 구성됩니다.
startline에는 프로토콜 버전, 상태 코드, 상태 텍스트 (ex. HTTP/1.1 404 Not found)
헤더에는 응답에 설정한 HTTP 헤더,
바디에는 요청에 대한 응답이 들어갑니다. 상태가 201(created), 204(no content)일 경우에는 보통 본문이 없습니다.
HTTP 프로토콜의 가장 큰 특징
HTTP 프로토콜에는 비연결성과 무상태성이라는 가장 큰 특성을 가지고 있습니다.
이 외에는 서버-클라이언트 구조, 요청, 응답 메시지, 상태코드, 메서드, 헤더 등등의 특성을 가집니다.
1. 비연결성(connectionless)
비연결성은 클라이언트와 서버가 연결을 맺은후에 응답을 마치면 기존의 연결을 끊는 특성을 말합니다.
장점)
HTTP가 연결을 유지하는 것으로 설계가 되었다면 서버에서는 다수의 클라이언트와의 연결을 유지하여야 합니다.
이에 따른 리소스가 많이 발생하게 됩니다.(관리해야하는 리소스는 클라이언트의 주소, 상태, 이전에 했던 요청들에 대한 정보 등과 같은 것들이 있을겁니다.)
연결을 유지하기 위한 리소스를 줄인다면 더 많은 연결을 할 수 있습니다.
단점)
서버에서는 클라이언트의 반복된 요청에도 매번 연결/해제의 과정을 수행해야 합니다.
이에 따른 오버헤드가 발생할 수 있습니다.
이러한 연결성을 보완하기 위한 HTTP 헤더가 있습니다. connection, keepAlive를 이용하면 됩니다.
HTTP2 에서는 이러한 헤더가 무시될겁니다. 무시되는 부분은 HTTP2 에 대한 공부가 더 되어야 설명가능할 것 같습니다.
connection에는 keepAlive, close를 설정할 수 있고
keepAlive에서는 max, timeout을 설정할 수 있습니다. max는 허용할 요청의 수이고 timeout은 지속 시간입니다.
example)
Connection: keepAlive
keepAlive: max = 5, timeout = 1000
2. 무상태성(stateless)
비연결성으로 인하여 무상태성(stateless)가 등장하게 되었습니다.
비연결성으로 인하여 이전에 어떠한 상태를 가지고 있는지 알수가 없습니다.
예를들면 로그인을 한후에 다음 페이지로 이동했을때 로그인을 한 상태를 알지 못하므로 다시 로그인을 요청할 수 있습니다.
이러한 무상태성을 보완하기 위해 쿠키, 세션이 등장하게 되었습니다.
쿠키는 브라우저에 세션은 DB에 저장되어 관리됩니다.
쿠키와 세션은 브라우저에 노출되어 위조가 일어날 수 있습니다.
세션은 세션ID만 노출이 되지만 쿠키의 경우에는 그대로 값이 노출됩니다.
따라서 Oauth, JWT와 같은 것들이 등장했습니다.
JWT(Json Web Token)은 header, payload, signature로 구성되어있으며
header에 암호화 알고리즘과 같은 정보들이 있고 signature를 이용해 원본 데이터를 암호화 하여 토큰을 생성합니다.
이 토큰을 쿠키 or 웹의 스토리지에 저장하고 사용하며
매 요청시마다 헤더에 추가되어 서버로 들어옵니다. 이 토큰이 갈취되거나 변조될경우 이전에 토큰을 암호화한 서명과 같지 않으면 요청이 성립되지 않으므로 보안성을 높인 기술이라 할 수 있습니다.
(Jwt에 대한 내용은 수정될 수 있습니다.)
URL 이란?
URL(uniform resource indicator)이란 웹 상에서 자원을 구별하는 식별자 입니다.
웹 에서는 파일을 자원 또는 리소스라고 부르는데 웹 상에서 자원을 구별하는데 사용하는 식별자가 URL 입니다.
URL은 웹에서 접근 가능한 자원의 주소를 표현하는 방식입니다.
ex) http://www.naver.com:80/example
프로토콜://호스트:포트/경로?쿼리
HTTP/1.1과 HTTP/2.0의 차이는?
1. binary framing (메시지 전송 방식의 변화, frame 분리 & 바이너리 인코딩)
2. multiplex streaming(하나의 tcp연결안에 여러 스트림이 존재 가능(스트림은 양방향 데이터 흐름))
2-1. Stream 우선순위 설정(리소스간 우선 순위를 설정 가능)
3. 중복헤더의 제거(헤더를 압축하고 중복된거는 이전 스트림에서 가져와 사용)
4. server push (클라이언트가 요청하지 않은 리소스를 서버에서 보내줄 수 있다)
HTTP 1.0에서 발생한 상황
매 요청마다 연결/해제의 과정이 발생하였습니다.
3번의 요청이 이루어진다면 3번의 연결/해제 과정이 이루어져야 했으므로 이로 인한 오버헤드가 발생했고 시간의 지연이 이루어졌었습니다.
이는 비연결성, 즉 연결 상태를 서버에서 관리하지 않음으로서 더 많은 연결을 할 수 있게 하기 위함이었습니다. http는 불특정 다수와 통신을 하게끔 설계되었기 때문입니다.
따라서 같은 클라이언트에서의 반복되는 연결일 경우 위에서 언급한 문제를 보완할 필요성이 대두되었습니다.
HTTP 1.1에서 해결한 방식
HTTP 1.1에서는 두개의 연결방식이 추가되었습니다.
Persistent connection 모델과 더 발전한 HTTP Pipelining 이었습니다.
Persistent connection은 연결의 지속 시간을 설정했습니다.
설정해둔 연결 지속시간에는 1.0에서 발생했던 연결/해제 의 과정을 하지 않아도 됩니다.
하지만 TCP의 특성상 요청후에 응답을 기다려야만 했습니다.
대기시간 동안에는 동작을 수행할 수 없었습니다.
Pipelining은 이를 개선한 모델입니다.
클라이언트에서는 요청을 응답에 상관없이 보내고 Server에서는 응답을 요청이 들어온 순서대로 보내줍니다.
이때 클라이언트에서는 응답의 순서가 잘못되거 중간에 빠졌다면 누락이 발생한 요청을 다시 보내게 됩니다.
하지만 문제가 없어보이는 Pipelining에도 문제가 발생합니다.
HOL(Heod Of Line) Blocking 문제였습니다.
클라이언트 에서는 1,2,3 번 요청을 보냈습니다.
서버에서는 1,2,3번을 처리하는데 각각 1번은 100초 2번은 20초 3번은 10초가 소요된다고 가정하겠습니다.
2,3번 요청은 이미 수행을 다 했지만 1번을 먼저 응답 보내야 하므로 2,3번 요청에 대한 응답은 계속 blocking이 됩니다.
이를 HOL Blocking이라 합니다.
HTTP 1.1에서 발생한 대표적 문제점
- HOL Blocking
- 연속된 요청간에 중복된 헤더들
HTTP 2.0에서 해결한 방식, 특성
1. binary framing
http1.1 에서 text 형식으로 전달되던 요청, 응답 메시지는 프레임 단위로 나누어지고 바이너리 형식으로 인코딩 됩니다.
바이너리는 컴퓨터가 더 이해하기 쉽습니다. 이로 인해 파싱, 전송 속도가 더 빨라졌습니다.
2. multiplex streaming
* Tcp 연결이 성립된후 N개의 스트림을 생성할 수 있습니다.
* 스트림은 파이프와 다르게 양방향 데이터 흐름이 가능하고 각 스트림에는 고유 식별자와 우선순위 정보가 있습니다.
* 각 메시지는 하나의 논리적 HTTP 메시지(요청 or 응답)이고 하나 이상의 프레임으로 구성됩니다.
* 프레임을 전달받은 쪽에서는 프레임의 헤더에 있는 스트림 식별자를 통해 프레임을 재조립하여 요청/응답 메시지를 확인할 수 있습니다.
3. 요청 및 응답 다중화
위의 그림은 3개의 병렬 스트림을 보여줍니다.
서버에서는
요청 1에 대한 data를 프레임 단위로 보내주고 있고
요청 3에 대한 header, data를 프레임에 추가하여 보내주고 있고
클라이언트에서는 요청 5에 대한 data를 서버에게 보내주고 있습니다.
HTTP 메시지를 독립된 프레임으로 세분화 했고 프레임을 받은쪽에서 다시 조립 합니다.
* 여러 요청을 하나도 차단하지 않고 병렬로 인터리빙할 수 있습니다.
* 여러 응답을 하나도 차단하지 않고 병렬로 인터리빙할 수 있습니다.
* 단일 연결을 사용하여 여러 요청과 응답을 병렬로 인터리빙할 수 있습니다.
HTTP 1.x에서 발생하던 HOL(Head Of Line Blocking)을 해결한 방식입니다.
HOL 차단은 클라이언트에서 1,2,3 요청을 했을때 서버에서 1을 200초, 2를 10초 만에 해결했어도 1이 먼저 응답이 되어져야 하므로 2에대한 응답이 그동안 blocking되는 것을 말합니다.
4. 스트림 우선순위 지정
5. 헤더 압축
압축에는 HPACK이라는 알고리즘을 사용하는데 이 알고리즘에는 정적 테이블과 동적 테이블이 존재합니다.
정적테이블에서는 공용 HTTP 헤더 필드를 제공하고 동적 테이블에서는 특정 연결시에만 값에 따라 업데이트가 됩니다.
각각의 값은 index 값을 가지고 헤더 전송이 시작될때 정적테이블, 동적테이블에 존재할 경우에는 index의 번호를 보내고 두개의 테이블에 없을 경우에는 Huffman 인코딩 방식을 사용하여 전송합니다.
6. server push
서버에서 a에 대한 요청이 왔을때 a에서 필요할것 같은것들을 이후에 보내버리는 방식입니다.
nginx에서 아래와 같이 설정이 가능합니다.
// 생략
http{
// 생략
server {
// 생략
listen 443 ssl http2;
root /sites/demo;
index index.html;
// 생략
location = /index.html {
http2_push /style.css;
http2_push /thumb.png;
}
// 생략
}
}
정리 표
HTTP 1.1 | HTTP 2.0 |
Persistent Connection | HTTP 메시지 전송 방식의 변화 |
Pipelining | 요청과 응답의 다중화(멀티플렉스 스트림) |
HTTP의 HOL(Head of Line Blocking) | 리소스간 우선순위 설정 |
Header 중복 | Server Push |
Header 압축 | |
TCP의 HOL(Head of Line Blocking) |
HTTP와 HTTP2.0은 둘다 TCP 기반이므로 TCP의 HOL(Head of Line Blocking)을 피할 수 없다
적용 방법
http2는 Nginx에서 http2 모듈을 추가해주면 세팅할수 있습니다
개발자 도구에서 확인한 예시
HTTP/1.1은 크롬 개발자 도구에서 생성된 메시지, 응답된 메시지 확인이 가능한데
HTTP/2.0은 확인이 불가능하다(구글, naver 예시) => 어차피 사람이 읽을수가 없음
출처: https://www.whatap.io/ko/blog/38/
https://minholee93.tistory.com/entry/Nginx-HTTP2
https://www.youtube.com/watch?v=xcrjamphIp4
https://developer.mozilla.org/ko/docs/Web/HTTP/Overview
https://developer.mozilla.org/ko/docs/Web/HTTP/Status/204
https://developer.mozilla.org/ko/docs/Web/HTTP/Messages
https://victorydntmd.tistory.com/286
https://developers.google.com/web/fundamentals/performance/http2/
'네트워크' 카테고리의 다른 글
주소창에 www.google.com을 입력하면?(성공과 실패를 결정하는 1% 네트워크 원리) (0) | 2022.04.17 |
---|---|
네트워크 HTTP, HTTPS, SSL HandShake 😶🌫️ (0) | 2022.04.17 |
html5, 웹 표준 및 웹 접근성 🔥 (0) | 2022.04.13 |
쿠키, 세션 🔥 (0) | 2022.04.11 |
CORS 🔥 (0) | 2022.04.03 |