DNS, 웹, 스트리밍
주소창에 이름을 치고 엔터를 누르면 1초도 안 되어 화면이 뜬다. 그 사이에 브라우저는 이름을 숫자 주소로 바꾸고, 가장 가까운 서버를 찾고, 수십 개의 파일을 한꺼번에 받아 온다. 지하철에서 보던 동영상은 터널에 들어가도 멈추지 않고 화질만 살짝 낮아진다. 이 장은 우리가 매일 쓰는 인터넷 서비스, 즉 응용 계층이 앞 장들의 도구를 어떻게 엮어 쓰는지 따라간다.
- 클라이언트-서버 방식과 P2P 방식의 차이와 장단점을 설명한다.
- DNS의 계층 구조(루트·TLD·권한 서버)와 재귀 리졸버, 캐시와 TTL의 역할을 따라간다.
- HTTP 요청·응답의 형식, 메서드와 상태 코드, 쿠키와 무상태성을 안다.
- HTTP/1.1, HTTP/2, HTTP/3가 페이지 로딩을 어떻게 바꿨는지 폭포수 그래프로 비교한다.
- CDN이 캐시 적중률로 응답 시간과 원본 서버 부담을 줄이는 원리를 계산한다.
- 적응형 비트레이트(ABR) 스트리밍이 버퍼와 화질 사이에서 균형을 잡는 방식을 체험한다.
- 실시간 통화가 일반 스트리밍과 다른 이유, 이메일·웹소켓·비트토렌트의 기본 구조를 안다.
응용 계층: 누가 누구에게 묻는가
지금까지 본 계층들은 “상자를 어떻게 옮길까”의 문제였다. 응용 계층은 “상자에 무엇을 담고, 어떤 순서로 대화할까”를 정한다. 웹 브라우저와 웹 서버의 HTTP, 메일 프로그램의 SMTP와 IMAP, 이름을 묻는 DNS가 모두 응용 계층 프로토콜이다. 이들은 앞 장의 TCP나 UDP(9장)를 그대로 가져다 쓴다.
대화 구조는 크게 두 가지다. 클라이언트-서버 방식에서는 항상 켜져 있고 주소가 잘 알려진 서버가 있고, 손님(클라이언트)들이 찾아와 요청한다. 웹, 메일, 대부분의 앱이 이렇다. 관리가 쉽고 일관되지만, 손님이 몰리면 서버와 서버 쪽 회선이 감당해야 한다. P2P(peer-to-peer) 방식에서는 참가자(피어)끼리 직접 주고받는다. 손님이 늘면 나눠 줄 사람도 함께 늘어나는 대신, 피어가 수시로 들어오고 나가며 NAT(7장) 뒤에 숨어 있어 연결이 까다롭다.
DNS: 인터넷의 주소록
라우터는 숫자 IP 주소(7장)만 안다. 하지만 사람은 203.0.113.7보다 www.example.com을 훨씬 잘 기억한다. 이름을 주소로 바꿔 주는 전 세계 분산 데이터베이스가 DNS(Domain Name System)다. 거의 모든 인터넷 통신이 DNS 조회로 시작한다.
“서울 강남구 ○○빌딩 3층 김 대리 번호 좀 알려 주세요.” 국가 안내소는 김 대리를 모르지만 “서울 안내소에 물어보세요”라고 알려 준다. 서울 안내소는 “○○빌딩 관리실에 물어보세요”라고 하고, 관리실이 마침내 번호를 알려 준다. 이 심부름을 대신 해 주고, 한 번 알아낸 번호는 수첩(캐시)에 적어 두는 비서가 재귀 리졸버다.
이름은 점(.)으로 나뉜 계층이고, 오른쪽이 위쪽이다. www.example.com.은 사실 맨 끝에 보이지 않는 점(루트)이 있다.
- 루트 서버(root server): 맨 위.
a.root-servers.net부터m.root-servers.net까지 13개의 이름이 있고, 12개 기관이 운영한다. 실제 서버는 같은 주소를 여러 곳에서 동시에 광고하는 애니캐스트(8장)로 전 세계 1,900곳이 넘는 곳에 흩어져 있어, 어디서 물어도 가까운 복제본이 답한다. - TLD(top-level domain) 서버:
.com,.org,.kr,.io같은 최상위 도메인을 맡는다. 약 1,500개가 있다..com은 Verisign이,.kr은 한국인터넷진흥원(KISA)이 운영한다. - 권한 네임서버(authoritative name server): 도메인 주인(또는 그가 맡긴 DNS 업체)이 운영하며, 그 도메인 안의 이름에 대한 “정답”을 갖고 있다.
.com 서버를, .com 서버는 example.com의 권한 서버를 알려 주고, 마지막 서버가 실제 IP 주소를 답한다.내 컴퓨터는 이 사슬을 직접 따라가지 않는다. 통신사나 공용 DNS(1.1.1.1, 8.8.8.8 등)가 운영하는 재귀 리졸버(recursive resolver)에게 “www.example.com의 주소를 알아다 줘”라고 한 번 묻는다. 리졸버가 루트 → TLD → 권한 서버를 차례로 묻고, 얻은 답을 각 기록에 붙은 캐시 수명(TTL, time to live)만큼 캐시에 보관한다. 같은 이름을 다시 물으면 루트까지 갈 필요 없이 바로 답한다. 실제로는 브라우저와 운영체제도 각자 작은 캐시를 갖고 있다.
DNS 조회의 여행: 캐시와 TTL
.com·example.com 서버를 건너뛰는지 보기 → “시간 +10분”으로 TTL 300초가 지나게 한 뒤 다시 조회. 돌려주는 주소는 문서용 예시 주소(203.0.113.x 등)다.www.example.com의 A 레코드 TTL이 5분이다. 처음 조회에 약 200 ms가 걸렸다. 2분 뒤 같은 리졸버를 쓰는 다른 사람이 같은 이름을 조회하면?
DNS 시뮬레이터에서 TTL을 5분으로 두고 두 번 조회해 보자.
DNS 데이터베이스에는 주소 말고도 여러 종류의 레코드가 들어 있다.
| 레코드 | 뜻 | 예 |
|---|---|---|
| A | 이름 → IPv4 주소 | www.example.com. 300 A 203.0.113.7 |
| AAAA | 이름 → IPv6 주소 | www.example.com. 300 AAAA 2001:db8::7 |
| CNAME | 다른 이름의 별명(“저쪽에 가서 물어봐”). CDN 연결에 많이 쓴다 | www.example.com. CNAME example.cdn-provider.net. |
| MX | 이 도메인 앞으로 온 메일을 받을 서버(우선순위 포함) | example.com. MX 10 mail.example.com. |
| TXT | 자유 문자열. 스팸 방지(SPF·DKIM·DMARC), 도메인 소유 인증 | example.com. TXT "v=spf1 mx -all" |
| NS | 이 영역을 책임지는 권한 네임서버(위임) | example.com. NS ns1.example.com. |
전통적인 DNS는 UDP 53번(9장)으로 암호화 없이 오간다. 그래서 같은 망의 누구든 내가 어떤 사이트를 찾는지 볼 수 있고, 가짜 답을 끼워 넣는 공격(DNS 스푸핑)도 가능하다. 요즘은 HTTPS 안에 DNS를 담는 DoH(DNS over HTTPS), TLS로 감싸는 DoT(853번)로 엿보기를 막고, 답에 전자 서명을 붙이는 DNSSEC으로 위조를 막는다(22장). 반대로 “사이트가 안 열린다”의 상당수는 DNS 문제다(23장).
HTTP: 요청하고 응답한다
주소를 알았으면 이제 웹 서버와 대화할 차례다. 웹의 언어 HTTP(HyperText Transfer Protocol)는 놀랄 만큼 단순하다. 클라이언트가 요청을 보내고 서버가 응답을 돌려준다. HTTP/1.1까지는 사람이 읽을 수 있는 글자로 되어 있다(요즘은 그 아래에 TLS 암호화를 깐 HTTPS가 기본이다, 22장).
| 메서드 | 뜻 |
|---|---|
| GET | 자원을 달라 (읽기) |
| POST | 데이터를 보낸다 (글쓰기, 결제, 로그인) |
| PUT / PATCH | 자원을 통째로 / 일부 바꾼다 |
| DELETE | 자원을 지운다 |
| HEAD | 본문 없이 헤더만 달라 |
| 상태 코드 | 뜻 |
|---|---|
| 200 OK | 성공 |
| 301 / 302 | 다른 주소로 이사 (영구 / 임시) |
| 304 | 바뀐 것 없음, 캐시 것을 써라 |
| 404 / 403 | 없음 / 권한 없음 |
| 429 | 요청이 너무 많다 |
| 500 / 503 | 서버 오류 / 일시적으로 감당 불가 |
첫 자리로 큰 뜻을 알 수 있다. 2xx 성공, 3xx 다른 곳으로, 4xx 손님 잘못, 5xx 서버 잘못. HTTP의 중요한 성질은 무상태성(stateless)이다. 서버는 요청 하나하나를 독립적으로 처리하고, 앞의 요청을 기억하지 않는다. 덕분에 서버 수천 대 중 아무 데로나 요청을 보내도 되어 규모를 키우기 쉽다. 그러면 로그인 상태나 장바구니는 어떻게 유지할까? 서버가 응답에 Set-Cookie로 작은 꼬리표를 붙이면, 브라우저가 이후 같은 사이트에 보내는 모든 요청에 Cookie로 그 꼬리표를 돌려준다. 이 쿠키(cookie)가 무상태 프로토콜 위에 “세션”을 만든다.
HTTP/1.1에서 HTTP/3까지: 페이지 하나를 빨리 받기
오늘날 웹 페이지 하나는 HTML 하나에 CSS, 자바스크립트, 이미지, 글꼴 등 보통 수십~백여 개의 파일로 이루어진다. 파일이 작고 많을수록, 대역폭보다 왕복 시간(RTT)이 로딩 시간을 지배한다. HTTP의 역사는 이 왕복을 줄이는 역사다.
- HTTP/1.1(1997): 연결 하나를 여러 요청에 재사용(keep-alive)하지만, 한 연결에서는 한 번에 하나씩 주고받는다. 앞의 응답이 끝나야 다음 요청을 보낼 수 있다. 그래서 브라우저는 서버 하나에 연결을 6개까지 열어 병렬로 받는다. 연결마다 핸드셰이크 비용과 슬로 스타트(9장)를 따로 치른다.
- HTTP/2(2015): 메시지를 작은 이진 프레임으로 쪼개고, 연결 하나 안에서 여러 요청·응답(스트림)을 섞어 보내는 스트림 다중화(multiplexing)를 한다. 매번 반복되는 헤더는 HPACK으로 압축한다. 다만 TCP 위에 있으므로 패킷 하나가 손실되면 모든 스트림이 멈춘다(9장의 헤드 오브 라인 블로킹).
- HTTP/3(2022): HTTP/2의 생각을 QUIC(9장) 위로 옮겼다. 연결 준비가 1 RTT 빠르고, 손실은 그 스트림만 멈춘다. 헤더 압축은 QPACK.
페이지 로딩 폭포수: HTTP/1.1 · HTTP/2 · HTTP/3
리소스 60개, 대역폭 50 Mbps, 손실 0%에서 RTT를 20 ms에서 200 ms로 늘렸다. HTTP/1.1과 HTTP/2의 로딩 시간 차이는 어떻게 될까?
폭포수 시뮬레이터의 세 결과 칸을 비교하자.
CDN: 가까운 곳에 미리 가져다 두기
아무리 프로토콜을 다듬어도 빛의 속도(5장)는 줄일 수 없다. 서울에서 미국 동부 서버까지의 RTT는 약 200 ms다. 남은 방법은 서버를 사용자 가까이 옮기는 것이다. CDN(content delivery network)은 전 세계 수백 곳의 거점(PoP)에 엣지 서버를 두고, 원본(오리진) 서버의 콘텐츠를 복사해 둔다. 사용자는 DNS나 애니캐스트로 가장 가까운 엣지에 연결된다.
인기 상품을 매번 본사 창고(오리진)에서 보내면 며칠이 걸린다. 그래서 택배 회사는 지역마다 물류 창고(엣지)를 두고 잘 팔리는 물건을 미리 쌓아 둔다. 주문이 들어오면 동네 창고에 재고가 있으면 당일 배송(캐시 적중), 없으면 본사에서 가져와 보내면서 다음 손님을 위해 창고에도 하나 남겨 둔다(캐시 실패 후 저장).
CDN의 성능은 캐시 적중률(cache hit ratio)에 달려 있다. 요청 중 엣지에 이미 사본이 있는 비율이다. 로고, 이미지, 동영상 조각처럼 모두가 같은 것을 받는 정적 콘텐츠는 적중률이 90%를 넘기 쉽다. 사람마다 다른 페이지나 결제 같은 동적 요청은 원본까지 가야 하지만, 이 경우에도 엣지가 TLS를 대신 맺고 원본과는 미리 열어 둔 연결을 재사용해 시간을 줄인다. 인터넷 트래픽의 절반 이상이 CDN을 거친다고 추정된다.
캐시 적중률과 평균 응답 시간
이메일과 실시간 웹
이메일은 웹보다 오래된(1982년 SMTP) 응용이고, 지금도 거의 같은 구조로 동작한다. 메일은 받는 사람의 컴퓨터로 바로 가지 않는다. 받는 사람이 꺼져 있을 수 있기 때문이다. 대신 항상 켜진 메일 서버가 우체국 사서함처럼 받아 두었다가 건네준다.
웹은 원래 “손님이 물어야 서버가 답하는” 구조라서, 채팅이나 주식 시세처럼 서버가 먼저 알려야 하는 일에는 어색했다. 예전에는 몇 초마다 “새 소식 있어?”를 묻는 폴링을 썼다. 웹소켓(WebSocket)은 HTTP 요청으로 시작해 서버가 101 Switching Protocols로 답하면, 그 TCP 연결을 양쪽이 아무 때나 메시지를 보낼 수 있는 통로로 바꾼다. 채팅, 협업 문서, 게임 로비, 실시간 알림이 이 위에서 돈다. 서버 → 브라우저 한 방향이면 더 단순한 SSE(Server-Sent Events)를, 최근에는 QUIC 위의 WebTransport도 쓴다.
동영상 스트리밍: 버퍼와 화질의 줄다리기
동영상은 인터넷 하향 트래픽의 약 3분의 2를 차지한다. 유튜브나 넷플릭스는 영상을 실시간 방송하듯 흘려보내지 않는다. 영상을 2~6초 길이의 조각(세그먼트)으로 잘라 평범한 파일처럼 CDN에 올려 두고, 플레이어가 HTTP로 한 조각씩 내려받아 이어 붙인다. 이 방식이 HLS(애플)와 MPEG-DASH다. 평범한 HTTP 파일이므로 CDN 캐시가 그대로 통한다.
핵심 비결은 같은 영상을 여러 화질로 미리 인코딩해 두는 비트레이트 사다리다. 플레이어는 조각마다 어느 화질을 받을지 고른다. 길이 막히면 다음 조각은 낮은 화질로, 넓어지면 높은 화질로. 이것이 적응형 비트레이트(ABR, adaptive bitrate) 스트리밍이다.
| 화질 | 해상도 | 대략적 비트레이트 | 1시간 데이터 |
|---|---|---|---|
| 240p | 426×240 | 0.4 Mbps | 약 0.2 GB |
| 360p | 640×360 | 0.75 Mbps | 약 0.3 GB |
| 480p | 854×480 | 1.2 Mbps | 약 0.5 GB |
| 720p | 1280×720 | 2.5 Mbps | 약 1.1 GB |
| 1080p | 1920×1080 | 5 Mbps | 약 2.3 GB |
| 1440p | 2560×1440 | 8 Mbps | 약 3.6 GB |
| 2160p (4K) | 3840×2160 | 16 Mbps | 약 7.2 GB |
숫자는 H.264/H.265 수준 코덱의 대표값이다. 같은 화질도 AV1 같은 최신 코덱은 30~50% 적게 쓰고, 움직임이 많은 스포츠는 더 많이 쓴다. 플레이어는 앞으로 재생할 조각을 버퍼에 쌓아 두고 재생한다. 버퍼가 바닥나면 화면이 멈추고 빙글빙글 도는 표시가 뜬다. 이것이 재버퍼링(rebuffering)이고, 시청자가 가장 싫어하는 순간이다. 화질을 높이면 버퍼가 빨리 줄고, 낮추면 화면이 흐려진다. ABR 알고리즘은 이 줄다리기를 한다.
- 처리율 기반: 최근 조각 몇 개를 받을 때 측정한 속도를 보고 “그보다 조금 낮은” 화질을 고른다. 반응이 빠르지만, 속도 측정이 흔들리면 화질도 오락가락하고 갑자기 떨어지면 버퍼가 바닥난다.
- 버퍼 기반(BBA 등): 버퍼가 넉넉하면 높은 화질, 줄어들면 낮은 화질을 고른다. 버퍼가 곧 안전 여유이므로 멈춤이 적다. 대신 시작 직후 버퍼가 비어 있을 때는 한동안 낮은 화질에 머문다. 실제 플레이어는 둘을 섞어 쓴다.
적응형 비트레이트: 대역폭이 흔들릴 때 플레이어는
‘지하철’ 시나리오에서 화질을 1080p로 고정하면, ABR(버퍼 기반)과 비교해 무엇이 달라질까?
ABR 시뮬레이터에서 알고리즘을 ‘고정 1080p’로 바꿔 보자.
실시간 통화와 P2P
유튜브는 버퍼를 30초씩 쌓아도 아무도 모른다. 하지만 영상 통화에서 상대의 말이 1초 늦게 들리면 대화가 무너진다. ITU-T 권고(G.114)는 대화가 자연스러우려면 한쪽 방향 지연을 150 ms 이내로 두라고 한다. 그래서 실시간 통화는 스트리밍과 완전히 다르게 만든다.
- UDP 위 RTP: 재전송을 기다릴 시간이 없으므로 TCP 대신 UDP(9장)에 RTP(실시간 전송 프로토콜)를 얹어 보낸다. 패킷마다 순서 번호와 시각 도장이 붙는다. 브라우저의 WebRTC가 대표적이다.
- 지터 버퍼: 패킷마다 도착 간격이 흔들린다(지터). 받는 쪽은 20~60 ms 정도의 아주 작은 버퍼를 두어 간격을 고르게 편 뒤 재생한다. 버퍼가 크면 끊김은 줄지만 지연이 늘고, 작으면 늦게 온 패킷을 버려야 한다.
- 손실은 숨긴다: 빠진 소리 조각은 앞뒤를 이어 그럴듯하게 채우고, 영상은 화질과 해상도를 실시간으로 낮춘다(이것도 일종의 ABR이다).
통화 한 번이 지나는 전체 경로, 즉 Wi-Fi와 셀룰러, NAT 통과, 지터 버퍼와 코덱은 24장 “영상 통화 한 번의 여행”에서 처음부터 끝까지 따라간다.
마지막으로 P2P를 다시 보자. 큰 파일을 수천 명에게 나눠 줄 때 서버 하나가 모두에게 보내면, 사람이 늘수록 시간이 정비례로 늘어난다. 비트토렌트(BitTorrent)는 파일을 수백 KB~수 MB 크기의 조각으로 나누고, 받는 사람끼리 서로 가진 조각을 주고받게 한다. 가장 드문 조각부터 받고(희귀 우선), 나에게 많이 보내 주는 상대에게 더 보내 주는(맞대응) 규칙으로 무임승차를 줄인다. 조각마다 해시값이 있어 변조도 막는다. 리눅스 배포판, 게임 패치 배포 등에 쓰인다.
파일 하나를 N명에게: 클라이언트-서버 vs P2P
핵심 정리
- 응용 계층은 TCP·UDP 위에서 “무엇을 어떤 순서로 주고받을지”를 정한다. 구조는 클라이언트-서버와 P2P로 나뉜다.
- DNS는 루트(13개 이름, 1,900곳 넘는 애니캐스트) → TLD → 권한 서버로 위임되는 분산 주소록이다. 재귀 리졸버가 대신 물어보고 TTL만큼 캐시해 대부분의 조회를 수 ms에 끝낸다.
- HTTP는 요청(메서드·경로·헤더)과 응답(상태 코드·헤더·본문)으로 된 무상태 프로토콜이고, 쿠키로 세션을 만든다.
- HTTP/1.1은 연결당 한 번에 하나, HTTP/2는 TCP 연결 하나에 다중화, HTTP/3는 QUIC 위에서 독립 스트림과 1-RTT 연결을 쓴다. RTT가 길수록 차이가 크다.
- CDN은 사용자 가까운 엣지에 사본을 두어 RTT와 원본 부담을 줄인다. 효과는 캐시 적중률이 좌우한다.
- 스트리밍은 2~6초 조각과 비트레이트 사다리로 ABR을 한다. 목표는 재버퍼링 없이 가능한 높은 화질이다.
- 실시간 통화는 한쪽 지연 150 ms 예산 때문에 UDP/RTP와 작은 지터 버퍼를 쓴다(24장). P2P는 받는 사람이 곧 나눠 주는 사람이 되어 규모가 커져도 버틴다.
확인 퀴즈
재귀 리졸버의 캐시가 비어 있을 때 www.example.com을 조회하는 순서로 옳은 것은?
메일을 받을 서버를 알려 주는 DNS 레코드는?
HTTP가 “무상태”라는 말의 뜻과, 그 위에서 로그인 상태를 유지하는 방법으로 옳은 것은?
HTTP/2가 HTTP/1.1보다 많은 작은 파일을 빨리 받는 핵심 이유는?
CDN의 캐시 적중률이 80%에서 95%로 오르면 가장 크게 줄어드는 것은?
영상 통화가 유튜브처럼 30초 버퍼를 두지 않고 UDP 위 RTP와 수십 ms의 지터 버퍼를 쓰는 이유는?