[CS] 네트워크 - 2. Application Layer

J.Noma·2022년 2월 13일
0

컴퓨터 공학

목록 보기
16/18

Reference

  • 내용전반: KOCW

Application Layer

🌀 기본개념

🔸 네트워크 Application(프로세스)

Application Layer는 네트워크 Application이 관할하는 영역이다. 네트워크 Application은 말 그대로 네트워크 기능이 있는 Application(프로세스)를 말한다. 가장 흔한 예로 웹브라우저가 있다. 네트워크 Application는 라우터라던지 하는 네트워크 구성들은 생각할 필요가 없고, 단순히 프로세스와 반대편에 있는 프로세스 간의 통신으로 다룬다. (참고로, 라우터에는 Application Layer가 없고 Network layer까지만 존재한다)

🔘 Process Communication
네트워킹은 결국 각 네트워크 Edge에 있는 client와 server간 의사소통인 것이다. 이는 OS에서 말하는 프로세스 간 통신 IPC(Inter-Process Communication)와 마찬가지로 두 프로세스 간 통신을 위해 Socket이라는 통로를 확보하며, 차이점은 프로세스가 존재하는 머신이 다르다는 특징이다. 그리고 이런 환경을 고려하여, 반대편에 존재하는 어떤 프로세스를 찾아가기 위해 IP address와 Port라는게 필요하다.

❗️NOTE
Server는 이 주소(IP+Port)가 변경되면 안된다

🔸 네트워크 App 개발자가 Transport Layer에게 요구할만한 것

아래 4가지를 요구하게 되지만, 실제론 1번 데이터 무결성만 TCP에 의해 지원되고 있다. 안해주니 별수 있나.. Application Layer에서 커버하게 된다 (ex. 보안을 위해 이 프로그램 깔아라)

  1. Data Integrity : 데이터 유실을 막아달라
  2. Timing : 시간 내에 빨리 도착하게 해달라
  3. Throughput : 최소 이정도 스루풋은 나와야 한다
  4. Security : 안전하게 보내달라

🔸 네트워크 App 별 사용하는 프로토콜

Transport 프로토콜은 대부분 TCP를 사용한다. Application 프로토콜 중에는 HTTP가 가장 유명하다


🌀 HTTP (Hyper-Text Transfer Protocol)

  • 이름 그대로 Hyper-text라는 것을 전송하는 프로토콜이다
    (* Hyper-Text : 일반 텍스트에 중간중간 다른 텍스트로의 링크가 있는 것)

  • Server-Client 구조를 가지며, 단순하게 서로 Request를 보내고 Response를 받는다

  • Transport 프로토콜로는 TCP를 사용한다
    (따라서, HTTP 메시지를 보내기 전에 TCP Connection이란걸 해야한다)

  • HTTP는 stateless하다

  • TCP connection 유지 여부에 따라 Persistent / non-Persistent로 나뉜다

🔸 Persistent / non-Persistent HTTP

🔘 Persistent
명시적으로 종료시킬 때까지 TCP Connection을 해제하지 않음. 현재 브라우저들은 Persistent를 디폴트로 쓴다

🔘 non-Persistent
메시지를 하나 처리할 때마다 TCP Connection을 연결/해제

🔘 non-Persistent의 응답시간
RTT(Round Trip Time)는 client-server를 왕복하는 시간을 말하며, non-Persistent HTTP의 응답시간을 계산하면 2RTT + 파일전송시간이 된다

🔸 연습문제: Delay 계산

Q. 아래 조건에서 persistent HTTP를 사용할 경우 end-to-end delay는 얼마인가?

  • TCP handshake = K bits
  • HTTP Request = K bits
  • Base HTML = L bits
  • N개의 참조 객체 = 각 L bits
  • 링크의 bandwidth = R bps
  • Propagation delay = d 초
  1. TCP Connection을 위한 control 메시지가 왕복해야 한다. Propagation delay와 Transmission delay가 2번씩 발생한다 = 2(K/R+d)
  2. HTTP Request가 전송된다 = K/R+d
  3. Base HTML을 받는다 = L/R+d
  4. N개의 참조 객체를 요청하고 받는다 = N*(K/R+d + L/R+d)

여기서, N개의 참조 객체를 한 번에 요청하고 한 번에 받는 방식으로 효율을 높일 수 있다

🔸 HTTP 메시지

우리는 어떤 프로토콜의 메시지가 어떤 필드들로 구성되어 있고 각 필드가 어떤 의미인지를 이해해야 한다. 그리고 이것들을 이해했다면 그 프로토콜을 다 이해한 것이다. 강의에서 TCP의 필드들은 다룰 예정이지만, HTTP 필드들은 하나하나 다루지 않는다

HTTP Request/Response의 필드들 중 가장 중요한 것은 공통적으로 첫번째 줄이다. Request의 첫번째 줄에는 어떤 요청인지(GET같은 HTTP메서드)와 파일명, HTTP버전이 명시되고, Response에는 HTTP버전, 요청결과(세자리 정수의 Status Code) 등이 온다

🔸 Status code

HTTP 요청에 대한 결과를 세자리 정수값으로 표현하며, 첫번째 숫자가 대분류 역할을 한다

  • 1xx : Information : 요청을 받아들여 처리 중
  • 2xx : Success : 요청이 정상적으로 처리됨
  • 3xx : Redirect : 요청을 완료하기 위해 추가 동작이 필요함
  • 4xx : Client Error : 서버가 요청을 이해할 수 없음
  • 5xx : Server Error : 서버가 요청 처리에 실패함

🔸 쿠키

HTTP는 stateless인 탓에 뭔가를 기억할 수 없는데, 로그인이라던지 뭔가를 기억하는게 필요한 서비스를 위해 쿠키로 HTTP를 보조한다

내용은 네트워크 : 세션 vs 토큰 vs 쿠키에 정리했었으므로 패스

🔸 프록시 서버

HTTP는 기본적으로 client-server 구조이지만, 현재의 HTTP 구조는 그 사이에 프록시라는 통신 중계기가 끼게 된다

내용은 네트워크 : 프록시 서버에 정리했었으므로 패스

🔘 Conditional GET
프록시와 같은 캐시들에는 근본적으로 데이터 일관성 문제가 있다. Conditional GET은 이 일관성 문제에 날짜를 기준으로 대응한다. client가 프록시에게 파일을 요청하면 프록시는 server에게 자신이 갖고 있는 파일이 최신인지를 묻는다. 최신이라면 그대로 client에게 보내고, 최신이 아니라면 server에게 파일을 받아 캐시 업데이트하고 client에게 보낸다

구체적으론, 프록시가 HTTP GET 메시지 필드에 if-modified-since: {date}를 추가하여 server로 보낸다. server는 명시된 날짜 이후에 해당 파일이 수정이 되었으면 수정된 파일을 response하고, 수정되지 않았으면 가지고 있던걸 쓰라는 의미로 파일없이 304 코드만을 response한다


🌀 DNS (Domain Name System)

🔸 DNS란?

이전에 언급했듯이 네트워킹을 위해선 상대편 프로세스의 IP주소와 포트를 알고 있어야 찾아갈 수 있다. 하지만 우리가 IP주소를 일일히 기억하기란 힘드므로 이를 대신해주는 서비스를 만들었는데 이게 DNS다. 그래서 DNS의 주소와 찾고자 하는 호스트네임(ex. naver.com)만 알고 있으면, IP주소는 DNS에게 물어봄으로써 알 수 있게 된다

🔸 문제점

이게 끝이면 별도의 챕터로까지 다룰 필요가 있었을까. 우리가 DNS를 만들기 위해 가장 단순한 방법으로 별도의 서버를 두고 거기에 "호스트네임-IP주소" 형태의 데이터를 저장하고 있다고 치자. 이렇게 하나의 서버에 모든 데이터를 두다보니 다양한 문제가 발생한다

  • 오류에 취약
    서버가 하나라서 다운이 발생하면 전세계 유저가 웹 사용에 제약을 받는다 (single-point failure)

  • 과도한 데이터크기
    문제는 이 데이터가 전세계가 공유해야 하므로 무지막지하게 크다는 것이다. DB관리는 둘째치고 검색시간이 그에 비례해서 무지막지하게 걸린다

  • 과도한 동시사용자
    모든 웹 사용에 DNS가 필요하므로 동시사용자 수가 무지막지하므로 서버가 터진다

🔸 해결방법 : 분산화, 계층화

어떤 것이든 규모가 커지면 감당이 안된다. 무조건 잘라서 계층화시켜야 한다

이미지출처 : https://www.cloudflare.com/ko-kr/learning/dns/glossary/dns-root-server/

  • root
    최상위에 존재하는 root 서버도 전세계 대륙별로 10군데 이상으로 분산되어 있다

  • TLD (top-level domain)
    .com / .org 등으로 분산되어 관리하는 서버들을 말한다

  • authoritative DNS
    특정 조직/기관이 보유한 서버를 말한다

  • Local DNS name server
    각 네트워크 기관들(ISP)이 마치 DNS 캐시처럼 상위 서버의 데이터를 캐싱하고 있는 것. 내부에서 요청되는 DNS 쿼리들에 캐싱 데이터로도 대응할 수 있다. 즉 우리집에서 날리는 어지간한 DNS 쿼리들은 SK브로드밴드 DNS 서버의 캐싱데이터로 대응된다

실제로 우리가 "velog.com"에 대한 DNS 서비스를 요청했다고 하자

  1. Local(SK브로드밴드)에게 요청한다. 여기서 캐시 hit이 나면 바로 유저에게 응답한다
  2. Root에게 어느 TLD로 가면 되는지 물어본다
  3. TLD(.com)에게 어느 authoritative로 가면 되는지 물어본다
  4. Local이 velog.com의 IP주소를 획득한다
  5. 유저에게 응답한다

🔸 DNS 레코드

DNS가 저장해야 하는 내용(레코드)은 대표적으로 호스트네임과 그에 대응되는 IP주소인데, 계층구조와 캐싱으로 인해 최종적으로 아래와 같은 포맷을 가지게 되었다. 이 레코드 포맷을 RR(Resource Record) 포맷이라고 한다

RR format : (name, value, type, ttl)

🔘 type
name과 value에 들어갈 내용은 type에 따라 달라진다. 아래와 같이 크게 4가지 type이 있다

  • type=A [ name=도메인네임, value=IP주소 ]
    엣지에 해당하는 Local과 authoritative에 주로 저장되는 레코드 타입이다. 일반적으로 우리가 기대하는 "naver.com / 102.204.282.1" 이런게 들어있다

  • type=NS [ name=도메인네임, value=도메인을 관리하는 호스트네임 ]
    NS는 "Name Server"의 약자로, 상위 계층들에 해당하는 Root와 TLD에 주로 저장되는 레코드 타입이다. IP주소를 당장 가지고 있진 않고, 특정 도메인의 IP주소를 알려면 어디로 가야 하는지가 적혀있다. 예로, ".com / dns.com" 이렇게 적혀있으며, 그 뜻은 ".com 도메인을 가진 호스트의 IP를 알려면 dns.com으로 가서 물어봐라"라는 뜻이다. 그리고, dns.com로 가서 물어보려면 또 IP주소가 있어야 하므로 "dns.com / 2.2.2.2"같은 type=A 레코드도 함께 저장되어 있어야 한다

  • type=CNAME [ name=도메인네임, value=도메인별명(Canonical Name) ]
    IP가 유동적으로 바뀌는 호스트에 주로 사용된다. 예로, type=CNAME "velog.com / foo.velog.com"에 더해, type=A의 "foo.velog.com / 3.3.3.3"와 함께 사용된다. 여러 도메인네임이 하나의 IP주소로 맵핑된 구조일 때, type=A로만 이루어진 경우 IP주소가 변경되면 모든 레코드를 수정해야 하지만 중간에 type=CNAME을 통하는 식으로 만들어놨다면 최종적인 type=A "foo.velog.com / 3.3.3.3"만 수정하면 된다

  • type=MX [ name=도메인네임, value=도메인과 관련된 메일서버네임 ]
    MX는 "Mail eXchange"의 약자로, 특정 도메인에 대한 메일을 수신하는 메일서버를 지정하는 레코드를 말한다

🔘 ttl
계층화 및 Local DNS의 캐싱 때문에 데이터 일관성 유지가 필요하다. 이를 위해 TTL (Time to Live)이라는 개념을 통해 특정 주기로 업데이트 하는 방식이 도입된다. TTL은 해당 레코드에 대해 유효기간을 설정하는 개념으로, TTL 시간이 지나면 해당 레코드가 만료되므로 원본 서버로부터 새로 가져와야 한다

IP주소는 잘 변경되지 않기에 ttl같은 러프한 방식을 기본적으로 사용하며, 경우에 따라 IP주소가 변경되었다는 notification을 전파할 수도 있다

🔸 DNS는 UDP를 사용한다

왜 안전한 TCP로 설계되지 않을걸까? 그 이유는 데이터 크기가 매우 작아서, 유실될 확률 자체도 낮고 유실되더라도 재요청 부담이 적기 때문이다. 그리고 DNS는 본래 네트워크 요청을 위한 에피타이저이므로, 엔지니어링 관점에서 가볍게 만들어졌다


🌀 Socket Programming

🔸 Socket이란?

네트워크 프로그래밍이란 결국 프로세스 간 메시지를 교환하는 것이다 (단지 프로세스들이 서로 다른 머신에 있어서 특이해보일 뿐). socket은 이를 위해 OS가 제공해주는 인터페이스(system call)를 말한다

socket도 TCP를 사용할지 UDP를 사용할지를 결정할 수 있다. 예로, TCP로 된 소켓으로 메시지를 보내면 유실되지 않고 안전하게 전달이 될 것이다

🔸 전체적인 흐름

아래는 TCP 소켓의 예이다

profile
노션으로 이사갑니다 https://tungsten-run-778.notion.site/Study-Archive-98e51c3793684d428070695d5722d1fe

0개의 댓글