IP
부터TCP
/UDP
~ HTTP
까지 이르는 전체 통신 흐름1969년 핵전쟁 대비 통신망 구축을 위해 시작된 아르파넷 프로젝트에서 기존의 회선교환 방식이 아닌 패킷교환 방식으로 네트워크를 구축하게 된다.
발신자 - 오퍼레이터 - 수신자
오퍼레이터가 발신자와 수신자 사이에 데이터를 연결할 전용선을 미리 할당하고 둘을 연결한다.
회선이 사용 중이면 연결이 끊어진 후에 상대방과 연결할 수 있다.
특정 회선이 끊어지면 처음부터 다시 연결을 성립해야 한다.
➞ 즉시성이 떨어진다는 단점이 있었다.
패킷이라는 단위로 데이터를 잘게 나누어 전송하는 방식
출발지와 목적지 정보를 갖는 패킷이 가장 효율적인 방식으로 목적지에 이동한다.
특정 회선이 전용선으로 할당되지 않기 때문에 빠르고 효율적으로 데이터를 전송할 수 있다.
인터넷 프로토콜은 출발지와 목적지의 정보를 IP 주소라는 특정한 숫자값으로 표기하고 패킷 단위로 데이터를 전송한다.
클라이언트와 서버는 컴퓨터에 IP(인터넷 프로토콜) 주소를 부여하여 이를 이용해 통신한다.
IP
는 IP 주소
에 패킷
이라는 통신 단위로 데이터를 전달한다.
IP 패킷
은 데이터를 전송하기 위한 출발지 IP, 목적지 IP와 같은 정보가 포함되어 있다.
클라이언트가
IP 패킷
을 전송하면 클라이언트와 서버의 인터넷 망 사이의 수많은 노드(서버 컴퓨터)들이 목적지 IP에 도달하기 위해 서로 데이터를 전달한다.
서버가 데이터를 전송받으면 마찬가지로
IP 패킷
을 이용해 클라이언트에 응답을 전달한다.
비연결성
패킷을 받을 대상이 없거나 서비스 불능 상태여도 클라이언트는 패킷을 전송한다.
비신뢰성
중간 노드에서 패킷이 소실될 수 있다.
전달 데이터의 용량이 클 경우, 각각의 패킷이 서로 다른 노드를 통해 전달됨에 따라 클라이언트가 의도하지 않은 순서로 서버에 패킷이 도착할 수 있다.
Transmission Control Protocol
전송 제어 프로토콜
IP 프로토콜보다 더 높은 계층에 TCP 프로토콜이 존재하기 때문에 IP 프로토콜의 한계를 보완할 수 있다.
- 연결 지향 - TCP 3 way handshake
- 데이터 전달 보증
TCP는 데이터 전송이 성공적으로 이루어진다면 이에 대한 응답을 돌려준다.
➞ IP패킷의 한계인 비연결성을 보완할 수 있다.
- 순서 보장
패킷이 서버에 순서대로 도착하지 않으면 TCP 세그먼트에 있는 정보를 토대로 다시 패킷 전송을 요청할 수 있다.
➞ IP패킷의 한계인 비신뢰성을 보완할 수 있다.
즉 TCP는 신뢰할 수 있는 프로토콜이다.
User Datagram Protocol
사용자 데이터그램 프로토콜
IP 프로토콜에 PORT, 체크섬 필드 정보만 추가된 단순한 프로토콜이다.
- 커스터마이징 가능
HTTP3는 UDP를 사용하며, 여러 기능이 구현된 TCP보다 하얀 도화지처럼 커스터마이징이 가능하다는 장점이 있다.
- 비 연결지향 - TCP 3 way handshake ❌
TCP에 비해 신뢰성이 낮지만 3 way handshake 방식을 사용하지 않기 때문에 TCP와 비교해 빠른 속도를 보장한다.
데이터 수신 여부 확인 ❌
전송 순서 보장 ❌
단순하고 빠르다.
➞신뢰성보다는 연속성이 중요한 서비스(실시간 스트리밍 등)에 자주 사용된다.
1984년 국제표준화기구(ISO)에서 제정한 네트워크 표준 규격
네트워크를 이루고 있는 구성요소들을 7단계로 나누고, 각 계층의 표준을 정한 것이다.
OSI 7계층 모델은 송신 측의 7계층과 수신 측의 7계층을 통해 데이터를 주고 받는다.
각 계층은 독립적이므로 데이터가 전달되는 동안에 다른 계층의 영향을 받지 않는다.
전송 측은 데이터를 보내기 위해 상위 계층에서 하위 계층으로 데이터를 전달한다.
데이터를 전송할 때 각 계층에서 필요한 정보를 데이터에 추가하는데, 이 정보를 헤더
(데이터 링크 계층에서는 트레일러
)라고 한다.
➡️ 이때 헤더를 붙여나가는 것을 캡슐화라고 한다.
마지막 물리 계층에서 송신 측의 데이터 링크 계층에서 만들어진 데이터가 전기 신호로 변환되어 수신 측에 전송된다.
수신 측은 하위 계층에서 상위 계층으로 전달된 데이터를 받는다.
➡️ 전달하는 동안 각 계층에서 헤더(또는 트레일러)를 제거해나가는 것을 역캡슐화라고 한다.
역캡슐화를 거쳐 응용 계층에서 도달하면 전송하려 했던 원본 데이터만 남게 된다.
OSI 7계층 모델을 기반으로 실무에 활용하기 좋게 단순화한 모델
현대의 인터넷 표준
어플리케이션 계층: TCP/UDP 기반의 응용 프로그램을 구현할 때 사용한다.
e.g. FTP, HTTP, SSH
전송 계층: 통신 노드 간의 연결을 제어하고, 신뢰성 있는 데이터 전송을 담당한다.
e.g. TCP/UDP
인터넷 계층: 통신 노드 간의 IP 패킷을 전송하는 기능 및 라우팅을 담당한다.
e.g. IP, ARP, RARP
네트워크 인터페이스 계층: 물리적인 주소로 MAC를 사용한다.
e.g. LAN, 패킷망 등에 사용됨
최상위 계층으로, 최종적으로 사용자와의 인터페이스를 제공한다.
이메일, 파일 전송, 웹사이트 조회 등 어플리케이션에 대한 서비스를 사용자에게 제공한다.
클라이언트가 사용하는 어플리케이션
: 웹 브라우저, FTP 클라이언트, 메일 프로그램 등
서버가 사용하는 어플리케이션
: 웹 서버 프로그램, 메일 서버 프로그램 등
클라이언트와 서버 모두 어플리케이션 계층에서 동작한다.
: 응용 계층의 대표적인 프로토콜
웹 사이트를 이용하기 위해 사용한다.
현재 주로 사용하는 HTTP/1.1은 1997년에 등장했으며 TCP 기반 프로토콜이다.
클라이언트가 서버에 request를 보내면 서버는 그에 대한 response를 보낸다.
클라이언트는 요청을 보내고 응답을 대기한다.
서버는 요청에 대한 결과를 만들어 응답한다.
서버가 클라이언트의 상태를 보존하지 않는다.
장점
서버 확장성이 높다 (스케일 아웃)
응답 서버를 쉽게 바꿀 수 있다. ➞ 무한한 서버 증설 가능
갑자기 클라이언트 요청이 증가해도 서버를 대거 투입할 수 있다.
단점
클라이언트가 추가 데이터를 전송한다.
클라이언트가 서버에 요청을 보낼 때 필요한 데이터를 모두 담아서 보내기 때문에 아무 서버나 호출해도 된다.
➞ 서버에 장애가 생기더라도 다른 서버에서 응답을 전달할 수 있기 때문에 클라이언트는 다시 요청할 필요가 없다.
➞ 응답 서버를 쉽게 바꿀 수 있다. (장점과 연결)
한계
모든 것을 무상태로 설계할 수 있는 경우도 있고 없는 경우도 있다.
로그인한 사용자의 경우 로그인했다는 상태를 서버에 유지해야 한다.
Connectionless : 연결을 유지하지 않는 모델
요청을 주고 받을 때만 연결을 유지하고, 응답을 주고 나면 TCP/IP 연결을 끊는다.
최소한의 자원으로 서버 유지를 가능하게 한다.
HTTP 1.0 기준으로 HTTP는 기본적으로 연결을 유지하지 않는 모델이다.
비연결성 모델은 트래픽이 많지 않고, 빠른 응답을 제공할 수 있는 경우 효율적으로 작동한다.
일반적으로 초 단위 이하의 빠른 속도로 응답한다.
한계
TCP/IP 연결을 새로 맺어야 함으로 3 way handshake 시간이 추가된다.
웹 브라우저로 사이트를 요청할 때 필요한 자원들을 각각 보낼 때마다 연결을 끊고 맺는 것은 비효율적이다.
➞ 현재는HTTP 지속 연결
로 문제를 해결한다.
연결이 이루어지고 난 뒤 필요한 자원들을 요청하고, 모든 자원에 대한 응답을 받은 후에 연결을 종료한다.
HTTP 전송에 필요한 모든 부가 정보를 담기 위해 사용한다.
표현 헤더는 요청, 응답 둘 다 사용한다.
<field-name>: <field-value> //field-name은 대소문자 구분이 없다.
Content-Type: 표현 데이터의 형식 //미디어 타입, 문자 인코딩
Content-Encoding: 표현 데이터의 압축 방식 //전달하는 곳에서 압축 후 인코딩 헤더 추가, 받는 쪽에서 인코딩 헤더의 정보로 압축 해제
Content-Language: 표현 데이터의 자연 언어
Content-Length: 표현 데이터의 길이 //byte 단위
콘텐츠 협상 (Content negotiation): 클라이언트가 선호하는 표현 요청
협상 헤더는 요청 시에만 사용한다.
원하는 콘텐츠에 대한 우선순위를 지정할 수 있다.
Quality Values(q): 1부터 0까지 우선순위를 부여하면 이를 토대로 서버는 응답을 지원한다.
생략하는 경우 = 1
1에 가까울수록 높은 우선순위를 가진다.
cache: 컴퓨터 과학에서 데이터나 값을 미리 복사해놓는 임시 장소
캐시 접근 시간에 비해 원래 데이터를 접근하는 시간이 오래 걸리는 경우나,
값을 다시 계산하는 시간을 절약하고 싶은 경우에 사용한다.
프라이빗 캐시: 개인의 컴퓨터에 저장
프록시 캐시: 여러 유저에게 공통적으로 보여지는 데이터
캐시가 없을 경우, 동일한 요청을 처리하기 위해 네트워크를 통해 같은 데이터를 다시 받아와야 한다.
➞ 느린 사용자 경험을 제공하게 된다.
웹에서 동일한 요청이 있으면 같은 데이터를 다시 다운로드하지 않고, 웹 캐시로 저장하여 빠르게 불러온다.
➞ 네트워크를 사용하지 않고 더 빠른 속도로 데이터에 접근할 수 있다.
➞ 브라우저 로딩 속도가 매우 빠르다.
브라우저에 캐시를 저장할 땐 cache-control 속성을 통해 캐시가 유효한 시간을 지정한다.
- 첫 번째 요청 ➞ 응답 결과를 캐시에 저장
- 두 번째 요청 ➞ 캐시 우선 조회, 유효한 캐시일 경우 캐시에서 데이터를 가져온다.
- 캐시 유효시간이 초과했을 경우 서버에 데이터를 요청하며 네트워크 다운로드가 발생한다.
기존 캐시를 지우고 새롭게 갱신한다. 캐시 유효 시간이 초기화된다.
캐시 유효 시간이 지났으나 데이터에 변경이 없다면 이를 검증하고 사용할 수 있는 방법이 있다.
Last-Modified: 캐시의 수정 시간을 알 수 있는 응답의 검증 헤더
If-Modified-Since: 조건부 요청 헤더
- 첫 번째 요청의 응답 결과를 캐시에 저장할 때 Last-Modified 헤더에 담긴 데이터 최종 수정일 정보가 담긴다.
- 두 번째 요청부터 캐시 유효시간이 초과되더라도 If-Modified-Since 헤더를 이용해 조건부 요청을 할 수 있다.
- 최종 수정일과 비교해서 데이터가 수정이 안되었을 경우
응답 메시지에서 Body없이 상태코드 304 Not Modified와 헤더 메타데이터를 보낸다.- 클라이언트에서는 응답을 받고 캐시를 갱신한다.
클라이언트는 캐시에 저장되어 있는 데이터를 재활용하며, 네트워크 다운로드가 발생하지만 용량이 적은 헤더 정보만 다운로드 한다.
매우 실용적인 해결책이 될 수 있다.
1초 미만 단위로 캐시 조정이 불가능하다.
날짜 기반의 로직을 사용하기 때문에 날짜가 다르지만 데이터 결과가 똑같은 경우를 알 수 없다.
ETag(Entity Tag): 서버에서 클라이언트에 응답할 때 캐시용 데이터에 임의의 고유한 버전 이름을 생성한다.
클라이언트의 캐시에 이를 저장하고, 데이터가 변경되면 Hash를 다시 생성하여 저장한다.
If-None-Match: 조건부 요청 헤더
- 데이터가 수정되었는지 ETag를 이용해 검증한다.
- 수정되지 않았다면 응답에서는 HTTP Body없이 HTTP 헤더만 전송한다.
상태코드 304 Not Modified- 브라우저 캐시에서 응답 결과를 재사용, 헤더 메타데이터 갱신
- 브라우저는 캐시에서 조회한 데이터를 렌더링한다.
Cache-Control: max-age //캐시 유효 시간. 초 단위
Cache-Control: no-cache //항상 원 서버에 검증하고 사용할 것
Cache-Control: no-store //데이터에 민감한 정보가 있으므로 저장하지 말 것
Expires: 캐시 만료일 지정(하위 호환)
Expires: 정확한 날짜 //캐시 만료일을 정확한 날짜로 지정한다.
지금은 Cache-Control: max-age 사용할 것
Cache-Control과 사용할 시 Expires는 무시된다.
프록시: 클라이언트와 서버 사이에 대리로 통신을 수행하는 것
프록시 서버: 중계 기능을 하는 서버
Cache-Control: public //응답이 public 캐시에 저장되어도 된다.
Cache-Control: private //응답이 해당 사용자만을 위한 것, private 캐시에 저장해야 한다.
Cache-Control: s-maxage //프록시 캐시에만 저장되는 max-age
Age: 60 (HTTP 헤더) //원 서버에서 응답 후 프록시 캐시 내에 머문 시간 (초 단위)
웹 브라우저가 임의로 캐싱을 할 때 Cache-Control 캐시 지시어를 통해 무효화할 수 있다.
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
no-cache는 프록시 캐시 서버와 원 서버 간의 접근이 불가능할 때 응답으로 오류가 아닌 200OK로 오래된 데이터를 보여준다.
must-revalidate는 원 서버에 접근이 불가할 때 504 Gateway Timeout 오류를 응답한다.
중요한 정보가 예전 데이터로 뜬다면 큰 문제가 생기기 때문에 must-revalidate를 사용해야 한다.