애플리케이션 계층 - 웹의 모든 것(HTTP, Cookie, Cash, Proxy)
웹은 OSI 7 Layers의 최상위 계층에서 동작하는 서비스로서 우리가 흔히 이용하는 네이버 웹 페이지, 구글 웹 페이지 등의 그 '웹'을 통칭한다.
웹의 특징은 크게 다음과 같다.
- 웹은 서비스를 원할 때 원하는 것을 수신받을 수 있는 On-Demand 서비스다.
- 웹은 원하는 것을 요구/수신받을 때 HTTP 프로토콜을 이용한다.
- 웹은 클라이언트-서버 구조다.
- HTTP는 비상태, 비지속 프로토콜이다.
- 서버가 사용자를 구분하기 위해 사용하는 것이 쿠키다.
- 웹 캐시(또는 프록시)는 서버의 응답 속도를 높이기 위해 사용된다.
지금은 이해가 잘 안될테지만 자세하게 하나씩 살펴가며 이해해보자.
1. 웹은 서비스를 원할 때 원하는 것을 수신받을 수 있는 On-Demand 서비스다.
인터넷 이전에 우리가 사용하던 TV/라디오를 생각해보자. 원하는 드라마를 보려면 방송사가 제공하는 시간에 특정 채널을 고정해야 원하는 드라마를 볼 수 있었다. 즉, 서비스 제공자가 서비스의 타이밍을 결정했다.
이와 다르게 웹은 우리가 원할 때 원하는 정보를 얻을 수 있다. 이처럼 시간과 주제에 규제받지 않는 서비스를 On-Demand 서비스 라고 한다. 웹은 클라이언트-서버 구조다. 서버는 항상, 24시간 내내 켜져있는 상태이기 때문에 우리는 시간에 규제를 받지 않는다.
2. 웹은 원하는 것을 요구/수신받을 때 HTTP 프로토콜을 이용한다.
HTTP[Hyper Text Transfer Protocol]은 웹이 서버로부터 원하는 것을 요구/수신할 때 사용하는 프로토콜이다. HTTP 프로토콜이란 웹 통신에 사용되는 최적의 메시지 구조와 방식을 정의해 놓은 프로토콜이다. HTTP가 지향하는 메시지 구조와 방식은 '객체'위주로 'URL'에 정보를 담아서 표현하는 것이다.
웹 내에서 주고받는 데이터는 단순히 글씨(텍스트)일수도 있고, 사진 또는 동영상, 아니면 HTML 파일 그 자체일수도 있다. 이처럼 웹과 클라이언트가 주고받는 데이터 하나를 객체[Object]라고 부른다. 이 객체는 URL로 지정할 수 있다.
예를 들어 www.good-network.com/users/Pictures.gif 라는 URL은 존재한다면, good-network.com 가 서버가 되고 그 뒤의 /users는 경로, Pictures.gif가 객체다.
이처럼 HTTP는 객체를 URL 위에 담아 표현하는 방식을 택하고 있으며 이를 잘~ 지켜서 통신하는 것을 Restful하다고 합니다.
3. 웹은 클라이언트-서버 구조다.
클라이언트-서버 구조에서 클라이언트는 정보를 요청하는 쪽, 서버는 정보를 제공하는 쪽이라고 앞선 포스팅에서 설명했다. 웹에서 정보를 제공하는 쪽은 항상 서버로 정해져있다.
웹에서 클라이언트-서버이 통신하는 방식을 자세히 살펴보자. 사용하는 HTTP 프로토콜은 기본적으로 TCP 기반 프로토콜이기 때문에 '연결 설정'이 필요하다.
- 클라이언트는 포트 80을 통해 서버로 TCP 연결을 시도한다.
- 서버와 연결이 이뤄지면 클라이언트는 HTTP 요청 메시지를 전송한다.
- 서버는 요청을 받고 서버 내에 존재하는 저장매체의 /users/ 경로에서 Pictures.gif 파일을 찾는다.
- 이 Pictures.gif를 캡슐화하여 서버의 소켓을 통해 메시지를 내보낸다.
- 서버는 TCP에게 연결을 끊으라고 요청한다.
- 클라이언트가 응답 메시지를 받으면 클라이언트-서버의 연결은 중단된다.
여기서 주목해야할 점은 클라이언트-서버의 TCP 연결이 객체를 한번 주고받으면 끝난다는 것이다. 즉, 요청 데이터가 세 개라면 연결은 세번 설정해야 된다는 의미가 된다. 이처럼 연결을 지속하지 않고 한번 주고받은 후 끊는 것을 비지속 연결이라 한다.
4. HTTP는 비상태, 비지속 프로토콜이다.
HTTP 서버는 비상태, 비지속 프로토콜이다. 즉 클라이언트 상태 정보를 저장하지 않는다. 데이터를 한번 주고받으면 끝- 이다.
만약 서버에서 연결되는 모든 클라리언트의 상태를 저장한다고 생각해보자. 네이버 같이 수 천명이 동시 접속하는 서버는 과부하가 걸릴 것이다. 이와 반대로 상태를 저장하지 않는다면, 메모리와 성능을 효율적으로 관리할 수 있으며 동시에 수천개의 TCP 연결을 다룰 수 있을 것이다.
물론 매번 TCP 연결을 끊어버린다면, 각 요청 객체 개수마다 그만큼의 새로운 TCP 연결을 설정해야 하기때문에 연결 설정에 대한 부하가 있다. 또한 모든 객체는 무조건 2RTT 을 필요로한다. (TCP 연결 1 RTT + 객체 요청/수신 1RTT)
cf. Round Trip Time[RTT]: 클라이언트가 파일을 요청하고 해당 파일이 다시 클라이언트까지 수신될 때의 왕복 시간
물론 지속 연결도 존재한다. 이는 서버가 요청에 대한 응답을 보낸 후에도 TCP 연결을 유지하다가 timeout이 지나면 연결을 닫는 방식이다. 그러나 HTTP는 해당 방식을 지원하지 않는다. 웹의 HTTP는 비지속, 비상태 프로토콜이라는 것을 잊지말자.
정리
비지속, 비상태 프로토콜의 장점
- 메모리와 성능의 효율적 관리 가능
- 수천 개의 TCP 연결 관리 가능
- 간단한 서버 설계가 가능
비지속, 비상태 프로토콜의 단점
- 객체의 개수마다 요청되는 TCP 연결 설정
- 각 개체는 무조건 2RTT 가 필요 (원래는 1RTT만 필요)
5. 서버가 사용자를 구분하기 위해 사용하는 것이 쿠키다.
통신 프로토콜인 HTTP는 비상태, 즉 사용자에 대한 정보를 저장하지 않는 것을 지향한다. 그러나 어떤 서버는 특정 사용자의 접속을 제한하거나 사용자마다 다른 콘텐츠를 제공하는 서비스를 제공하고 싶을 수도 있다. 이를 위해 사용자 신원을 확인하고 싶을 수도 있다. 이때 사용되는 것이 웹 쿠키[Cookie]다,
쿠키를 이용한 클라이언트-서버는 다음과 같이 동작한다.
- 효리는 처음으로 쿠팡에 접속했다.
- 효리의 웹은 쿠팡에 접속을 요청한다. 이때 쿠팡 서버는 효리 웹에 대한 고유 ID를 만들고 이를 쿠팡 서버에 저장한다. 이 고유ID를 쿠키라고 한다.
- 그후, 쿠팡 서버는 효리의 웹에게 쿠키를 포함한 HTTP 응답을 보낸다.
- 효리의 웹은 해당 응답을 받고 쿠팡 서버에서 자신의 쿠키 번호를 알게된다. (예를 들어 쿠키 ID는 123이라고 가정)
- 효리의 웹은 자신의 브라우저에도 (쿠팡,123)를 저장한다.
- 쿠팡 서버는 이 '123' 사용자가 몇 시에 어떤 상품을 방문하는지에 대한 로그 정보를 저장한다.
- 효리가 쿠팡에 재방문하면 수진이 웹은 아마존에게 접속을 요청한다. 이때, 자신의 쿠키에 저장해놓은 쿠키 ID '123' 을 함께 보낸다.
- 아마존 서버는 해당 방문자가 '123' 이라는 것을 인식하여 그동안 모아놓은 '123'이 관심있었던 상품들 등에 대한 정보를 기반으로 다양한 서비스를 제공한다.
6. 웹 캐시(또는 프록시)는 서버의 응답 속도를 높이기 위해 사용된다.
사람들이 가장 자주 방문하는 웹페이지는 어딜까? 네이버? 구글? 아마존? 구글과 같은 페이지는 전세계적이기 때문에 사용자 수가 굉장히 많을 것이다. 따라서 하나의 서버로 그 많은 클라이언트의 요청을 처리하는 것은 불가능하다. 따라서, 구글은 구글 서버를 굉장히 여러 지역에 분산하여 저장할 것이고 분산된 서버에서 각 지역의 클라이언트들을 커버하고 있을 것이다.
그러나 똑같은 서버를 여러 개 구현해서 각 지역에 배포를 한다면, 수천 억개의 데이터를 저장하는 서버가 전 세계 지역 수만큼 배포되어야 하는 것이기 때문에 굉장히 큰 비용이 들 것이다. 따라서 각 지역에 배포된 서버에 저정된 데이터의 양은 'All'이 아니라 'Some'이다. 웹 캐시는 'some'의 데이터 때문에 등장했다.
컴퓨터구조에서 배우는 CPU 옆 캐시가 어떤 역할을 하는지 기억하는가? CPU가 필요로 할 것 같은 데이터를 예측하여 메인메모리에서 가져와 저장하는 것이다. 이렇게 함으로서 CPU와 메인메모리 사이의 통신 속도를 더욱 빠르게 할 수 있다.
웹 캐시도 마찬가지다. 클라이언트가 필요로 할 것 같은 데이터를 미리 서버로부터 가져와서 적재한다. 그 후 적재된 데이터로 클라이언트에게 응답하는 것이다. 이때 웹 캐시에 적재된 데이터는 최근에 호출된 객체 정보다. 웹 캐시의 동작방법은 다음과 같다.
- 나의 웹은 구글 웹 캐시와 TCP 연결을 설정한다. 그후, 찾고싶은 데이터에 대한 요청을 웹캐시에게 보낸다.
- 웹캐시는 해당 데이터가 자신의 메모리 내에 존재하는지 확인한다.
- 있다면 요청 데이터를 바로 클라이언트에게 전송한다.
- 없다면, 웹 캐시는 원래 구글 서버와 TCP 연결을 설정하고 서버에게 해당 데이터 요청을 보낸다.
- 구글 서버는 웹 캐시에게 해당 데이터를 보내준다.
- 웹 캐시는 해당 데이터를 클라이언트에게 다시 전달해 주고 자신의 메모리에도 저장한다.
이처럼 웹 캐시는 정보를 제공해주는 서버이자 정보를 요청하는 클라이언트가 된다. 일반적으로 웹 캐시는 인터넷 관리자인 ISP가 구입하고 설치한다.
웹 캐시를 사용함으로써의 장/단점은 다음과 같다.
- 데이터 요청에 대한 응답시간을 줄일 수 있다.
- 서버와 클라이언트 사이의 병목현상을 방지할 수 있다.
- 기업/기관들(=서버)은 접속하는 네트워크 링크 트래픽을 대폭 줄일 수 있으므로 비용 절약이 가능하다.
- 단점으로는 캐시 내부의 데이터는 최신이 아닐 수도 있다. (업데이트의 문제)
일반적으로 웹 캐시의 단점은 업데이트 문제가 있다. 그러나 다행이도 HTTP 프로토콜은 항상 이 객체가 최신임을 보장한다. 이를 위해 "조건부 GET"을 활용한다. 브라우저는 요청을 할 때 항상 조건부 GET을 통해 해당 객체의 업데이트 내역을 조사한다.
조건부 GET을 서버에게 보낸다. 이는 해당 객체가 주어진 날짜 이후에 수정되었는지를 물어보면서 만약 수정되었다면 그 객체를 보내달라는 의미다. 서버는 변경되지 않았더라면 'Not Modified'를 보낸다. 요청 메시지 자체를 포함하는 것은 대역폭을 낭비하는 것이기 때문에 간단한 조건부GET 패킷만 보냄으로써 비용과 시간을 절약할 수 있다.