CS/Network

[Network]애플리케이션 계층과 HTTP

frog-in-well 2022. 7. 26. 09:03

1. 네트워크 애플리케이션

1.1 프로세스 간 통신

네트워크 애플리케이션이 통신할 때 실제 통신하는 것은 프로그램이 아닌 프로세스다. 같은 종단 시스템에서 실행되는 프로세스들의 통신은 운영체제에서 자세하게 다루는 내용이다. 서로 다른 종단 시스템에서 프로세스들은 네트워크를 통해 메시지를 교환한다.

클라이언트와 서버

  • 네트워크 애플리케이션은 네트워크에서 서로 메시지를 보내는 두 프로세스로 구성된다. (ex. 웹 애플리케이션에서 클라이언트 브라우저 프로세스는 웹 서버 프로세스와 메시지를 교환한다. P2P 파일 공유 시스템에서 한 피어의 프로세스에서 다른 피어의 프로세스로 파일을 전송한다.)
  • 네트워크를 통해 통신하는 프로세스는 클라이언트 프로세스와 서버 프로세스 중 하나로 이름 짓는다.

소켓

프로세스가 집이라면 소켓은 일종의 출입구 역할을 한다. 소켓은 호스트의 애플리케이션 계층과 트랜스포트 계층 간의 인터페이스이다. (Application Programming Interface)

  • 프로세스는 소켓을 통해 네트워크로 메시지를 주고 받는다.
    • 프로세스가 메시지를 다른 호스트의 프로세스로 보내고 싶을 때, 송신 프로세스의 소켓의 바깥 네트워크로 메시지를 밀어낸다.
    • 메시지가 목적지 호스트에 도착하면 메시지는 수신 프로세스의 소켓을 거쳐 들어온다. 수신 프로세스는 메시지를 처리한다.
  • 소켓 인터페이스의 주소를 정확하게 알아야 통신이 가능하다. 이 떄 주소는 IP주소와 포트 번호로 결정된다.

2. 웹과 HTTP

웹은 사용자가 필요에 따라 웹 서버로부터 문서를 얻게 해주는 네트워크 애플리케이션이다.

웹 애플리케이션은 HTML, 웹 브라우저, 웹 서버 및 다양한 웹의 요소들로 구성된다.

웹 애플리케이션 계층 프로토콜인 HTTP는 브라우저와 웹 서버 사이에서 교환되는 메시지의 포맷과 순서를 정의한다.

2.1 HTTP

  • HTTP(Hypertext Transfer Protocol)은 웹의 애플리케이션 계층 프로토콜이다.
  • 웹 클라이언트가 웹 서버에게 웹 페이지를 어떻게 요청하는지와 서버가 클라이언트로 어떻게 웹 페이지를 전송하는 지를 정의한다.
  • HTTP는 TCP를 전송 계층 프로토콜로 사용한다. (중간에 유실 없이 신뢰성 있게 통신 가능하다.)
  • 클라이언트 측에서 보면 소켓 인터페이스는 클라이언트 프로세스와 TCP 연결 사이에서의 출입구다. 클라이언트는 HTTP 요청 메시지를 소켓 인터페이스로 보내고 소켓 인터페이스로부터 HTTP 응답 메시지를 받는다.
  • 서버 측에서는 소켓 인터페이스로부터 요청 메시지를 받고 응답 메시지를 보낸다.
  • 서버가 클라이언트에게 응답 메시지를 보낼 때, 서버는 클라이언트에 관한 어떠한 상태 정보도 저장하지 않는 비상태 프로토콜이다.(stateless protocol) → 쿠키 사용

2.2 비지속 연결과 지속 연결

클라이언트와 서버의 메시지 교환이 매번 새로운 TCP 연결에서 이루어지는지 같은 TCP 연결에서 이루어지는지에 따라 비지속 연결과 지속 연결로 분류된다.

비지속 연결 HTTP

  • HTTP 클라이언트는 HTTP의 기본 포트 번호 80과 서버의 IP 주소를 이용해 TCP 연결을 시도한다.
    • 이 때, 클라이언트와 서버에 각각 소켓이 생긴다.
  • HTTP 클라이언트는 TCP 연결 소켓을 통해 HTTP 요청 메시지를 보낸다.
  • HTTP 서버는 TCP 연결 소켓을 통해 요청 메시지를 받고 응답 메시지를 보낸다.
  • HTTP 서버는 TCP에게 TCP 연결을 끊으라고 한다.
  • HTTP 클라이언트가 응답 메시지를 받으면 TCP 연결이 중단된다.

위와 같은 TCP 연결 - HTTP 메시지 교환을 모든 HTTP 메시지마다 반복한다.

RTT

RTT는 패킷이(3-way handshake를 위함) 클라이언트로부터 서버까지 갔다가 다시 클라이언트로 되돌아 오는 시간이다.

  • TCP 연결을 시도할 때, 3-way handshake가 발생한다. 처음 두 부분이 경과하면 하나의 RTT가 계산된다.
  • 세번째 부분에서 클라이언트는 HTTP 요청 메시지를 TCP 연결로 보내며 응답을 함께 보낸다.
  • 일단 요청 메시지가 서버에 도착하면 서버는 HTML 파일을 TCP 연결로 보낸다.

결국 HTTP 요청/응답에 걸리는 시간은 총 2RTT와 HTML 파일을 서버가 전송하는데 걸리는 시간의 합이다.

지속 연결 HTTP

비지속 연결에는 몇가지 단점이 존재한다. 각 요청 객체에 대한 새로운 연결이 설정되고 유지 되기 위해 TCP 버퍼가 할당되어야 하고 TCP 변수들이 클라이언트와 서버 양쪽에 유지되어야 한다. 이는 수많은 요청을 동시에 수행할 때 심각한 부담이다.

  • HTTP 1.1에서는 지속 연결을 제공한다. (keep-alive)
  • 하나의 지속 TCP 연결을 통해 여러 HTTP 요청/응답이 가능하다.
  • 객체에 대한 요청을 응답을 기다리지 않고 연속해서 만들어질 수 있다. (pipelining)

HTTP 버전 참고 - https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP

2.3 HTTP 메시지 포맷

HTTP 요청 메시지

  • 요청 라인(첫 줄) - method 필드, URL 필드, HTTP 버전 필드
  • 헤더 라인

HTTP 응답 메시지

  • 상태 라인 - HTTP 버전 필드, 상태 코드, 해당 상태 메시지
  • 헤더 라인
  • 개체 몸체(entity body)

2.4 쿠키

HTTP 서버는 상태를 유지하지 않는다. 이는 서버 설계를 간편하게 한다. 하지만 사용자에 따라 콘텐츠를 제공하거나 특정 사용자 접속을 제한하는 등의 사용자 확인이 필요할 때가 있다. 이를 위해 HTTP는 쿠키를 사용한다. (세션을 사용하기도 한다.)

쿠키와 세션

2.5 웹 캐싱

웹 캐시(프록시 서버)는 자체의 저장 디스크를 갖고 있어 최근 호출된 객체의 사본을 저장하고 있다. 웹 캐시를 이용하여 사용자의 모든 HTTP 요구가 웹 캐시에 가장 먼저 보내지도록 구성할 수 있다.

캐시는 서버이면서 동시에 클라이언트다. 일반적으로 ISP가 웹 캐시를 구입하고 설치한다.

웹 캐시를 통한 객체 요청 과정

  • 브라우저는 웹 캐시와 TCP 연결을 설정하고 웹 캐시에 있는 객체에 대한 HTTP 요청을 보낸다.
  • 웹 캐시에 객체의 사본이 저장되어 있는지 확인한다.
    • 저장되어 있다면 클라이언트 브라우저로 HTTP 응답 메시지와 함께 객체를 전송한다.
  • 웹 캐시에 객체를 가지고 있지 않다면 원출처의 서버에 TCP 연결을 설정한다.
  • 웹 캐시는 서버 간의 TCP 연결로 객체에 대한 HTTP 요청을 보낸다. 서버는 웹 캐시에 HTTP 응답 메시지와 함께 객체를 보낸다.
  • 웹 캐시가 객체를 수신할 때, 객체를 자신의 저장 장치에 복사하고 클라이언트 브라우저에 HTTP 응답 메시지와 함께 객체의 사본을 보낸다.

웹 캐시의 장점과 단점

웹 캐시의 장점으로는

  • 웹 캐시는 클라이언트의 요구에 대한 응답 시간을 줄일 수 있다.
  • 웹 캐시는 한 기관에서 인터넷으로 접속하는 링크상의 웹 트래픽을 대폭으로 줄일 수 있다. 기관은 자주 대역폭을 개선할 필요가 없어 비용을 절약할 수 있다. (서버 또한 트래픽이 감소해 성능 개선에 도움이 된다.)

웹 캐싱을 통해 응답 시간을 줄일 수 있지만 문제 또한 발생한다. 캐시 내부에 존재하는 객체의 복사본이 최신의 것이 아닐 수 있다. 이를 해결하기 위해 조건부 GET 방식을 사용한다.

조건부 GET 요청

HTTP 요청 메시지가 (1) GET 방식을 사용하고 (2) If-Modified-Since 헤더 라인을 갖고 있다면 조건부 GET 요청이다.

  • 브라우저의 요청을 대신해서 프록시 캐시는 요청 메시지를 웹 서버로 전송한다.
  • 웹 서버는 캐시에게 객체를 가진 응답 메시지를 보낸다. (Last-Modified 헤더 포함)
  • 캐시를 요청하는 브라우저에게 객체를 보내고 자신에게도 객체를 저장한다. (이 때 Last-Modified 정보를 함께 저장)
  • 시간이 지난 후 다른 브라우저가 같은 객체를 캐시에게 요청할 때, 객체는 여전히 저장되어 있지만 최신 여부를 확인하기 위해 조건부 GET 요청을 보낸다. (If-Modified-Since에 캐시에 저장된 Last-Modified 정보 담음)
  • 웹 서버는 If-Modified-Since를 확인하고 해당 날짜 이후 객체가 변경되지 않았다면 304 Not Modified 상태와 함께 빈 객체 몸체를 응답 메세지로 보낸다.

3. DNS

DNS는 호스트 네임을 IP 주소로 변환 해주는 서비스이다. DNS 서버들의 계층구조로 구현된 분산 데이터베이스이며 호스트가 분산 데이터베이스로 질의하도록 하는 애플리케이션 계층 프로토콜이다.

3.1 DNS의 서비스

  • 브라우저가 호스트 네임을 DNS 애플리케이션의 클라이언트 측에 넘긴다.
  • DNS 클라이언트는 DNS 서버로 호스트 네임을 포함하는 질의를 보낸다.
    • 53번 포트, UDP 사용
  • DNS 클라리언트는 IP 주소를 가진 응답을 받게 된다.
  • 브라우저가 DNS로부터 받은 IP 주소를 이용해 80번 포트에 위치하는 HTTP 서버 프로세스로 TCP 연결을 시도한다.

호스트 엘리어싱

복잡한 호스트 네임을 가진 호스트는 하나 이상의 별명을 가진다. DNS는 호스트의 IP 주소뿐만 아니라 별칭 호스트 네임에 대한 정식 호스트 네임을 얻기 위해 사용될 수 있다.

3.2 DNS의 동작

만약 DNS가 단일 서버로 설계되었다면

  • 확장성에 어려움이 있을 것이다.
  • 네임 서버가 고장나면 전체 인터넷이 작동하지 않을 것이다.
  • 모든 DNS를 처리하기 위해 트래픽이 집중될 것이다.
  • 거리가 멀리 위치한다면 혼잡한 링크를 거쳐 여행을 해야할 것이다.

분산 계층 데이터베이스

  • 우선, DNS 클라이언트는 www.naver.com 호스트 네임의 IP 주소를 얻기 위해 DNS 루트 서버 중 하나에 접속한다.
  • 루트 서버는 최상위 레벨 도메인 com을 갖는 TLD 서버 IP 주소를 보낸다.
  • 클라이언트는 TLD 서버에 접속하고 TLD 서버는 naver.com를 가진 책임 서버의 IP 주소를 보낸다.
  • 클라이언트는 naver.com의 책임 서버 중 하나에 접속한다. 책임 서버는 이제 www.naver.com의 IP 주소를 보낸다.

DNS 캐싱

로컬 DNS 서버는 대체로 호스트 가까이에 위치한다.

  • 호스트가 DNS 질의를 보내면 가장 먼저 프록시로 동작하는 로컬 DNS 서버에게 전달된다.
  • 로컬 DNS 서버에 매핑이 존재하지 않으면 로컬 DNS 서버는 루트 DNS 서버에게 질의를 전달한다.
  • 루트 DNS 서버가 TLD DNS 서버의 IP 주소를 알려주면 로컬 DNS 서버에 저장된다.
  • 재귀적으로 호스트 네임에 대한 IP 주소까지 로컬 DNS 서버에 저장된다.

DNS 동작 정리

  • www.frog.blog.com을 검색한다.
  • 대부분의 로컬 DNS 서버에 매핑이 존재한다.
  • 만약 없다면, 루트 DNS 서버에 질문을 하고 답변이 로컬 DNS 서버에 전달된다.
  • 하위 DNS 서버로 재귀적으로 질문과 답변을 얻으며 최종적으로 하나의 A 레코드(IP 주소)를 받는다.

3.3 DNS 레코드

  • 항상 Type=NS와 Type=A는 한쌍으로 다녀야한다.
    • NS : 특정 도메인 frog.com (Name)의 IP 주소를 얻을 수 있는 방법을 알고 있는 DNS 서버의 호스트 네임 dns.frog.com (Value)
    • A : 위의 DNS 서버의 호스트 네임 dns.frog.com(Name)과 IP 주소 192.37.93.126 (Value)
  • 결국 가장 하위 DNS 서버에는 누구에게 물어보라는 정보 없이 Type=A 레코드가 전부일 것이다.

 

출처 - 컴퓨터 네트워킹 하향식 접근 2장 - Application Layer