Chapter 11

웹 페이지가 열리기까지

주소창에 주소를 치고 Enter를 누르면 1초도 안 되어 페이지가 뜬다. 그 짧은 순간에 브라우저는 서버의 위치를 묻고, 연결을 맺고, 비밀 대화 통로를 만들고, 페이지를 요청하고, 받은 글자를 그림으로 바꾼다. 이 장에서는 이 과정을 슬로 모션으로 재생해 본다. 앞 장들에서 배운 거의 모든 것이 여기서 함께 등장한다.

URL 읽기: 인터넷의 주소 형식

웹 주소, 즉 URL(Uniform Resource Locator)은 몇 개의 부분으로 나뉜다. 아래에 아무 주소나 넣어 보자.

SIMULATOR

URL 해부기

전체 그림: 0.5초의 폭포

웹 페이지 하나가 열리는 과정은 대략 다음 순서로 진행된다. 각 단계는 앞 단계가 끝나야 시작할 수 있어서 계단식 폭포처럼 보인다. 개발자 도구(F12)의 “네트워크” 탭에서 실제 사이트의 폭포 그래프를 볼 수 있다.

SIMULATOR

페이지 로딩 폭포 그래프

서버까지의 거리 (왕복 지연)
방문 상태
화면에 처음 뜨기까지—
왕복 횟수—
시간 중 “기다림”의 비율—
해볼 것: 서버를 미국으로 바꾸면 대역폭을 아무리 올려도 느리다. 연결을 맺는 데만 왕복이 여러 번 필요하기 때문이다(10장의 지연). “다시 방문”에서는 DNS 결과와 이미지가 캐시에 있어 단계가 크게 줄어든다. 그래서 큰 사이트들은 전 세계에 서버 복사본(CDN)을 두어 사용자와의 거리를 줄인다.

DNS: 인터넷의 전화번호부

컴퓨터는 www.example.com 같은 이름으로는 연결할 수 없다. 10장에서 본 IP 주소가 필요하다. 이름을 IP 주소로 바꿔 주는 시스템이 DNS(Domain Name System)다. 사람 이름으로 전화번호를 찾는 전화번호부와 같다.

전 세계 수억 개의 도메인을 한 곳에서 관리할 수는 없으므로 DNS는 계층으로 나뉜다. 주소를 오른쪽부터 읽는다. .com을 아는 서버, example.com을 아는 서버를 차례로 물어 찾아간다. 한 번 찾은 결과는 여러 곳에 캐시해 두어 다음에는 바로 답한다.

루트 ( . ) .kr .com .org .net example.com google.com wwwmail 주소는 오른쪽부터 읽는다 www . example . com . ← 좁은 범위 넓은 범위 →
그림 11-1. DNS의 나무 구조. 루트 서버는 .com을 아는 서버를, .com 서버는 example.com을 아는 서버를 알려 준다. 각 단계가 자기 아래만 책임지므로 수억 개의 이름도 나눠서 관리할 수 있다.
SIMULATOR

DNS 조회 따라가기

예측해 보기

인터넷 연결은 멀쩡한데 DNS 서버만 고장 났다. 어떤 일이 생길까?

DNS가 하는 일이 무엇이었는지 떠올려 보자.

길(네트워크)은 멀쩡한데 전화번호부가 사라진 셈이다. 이름을 IP로 바꾸지 못해 거의 모든 사이트가 안 열린다. 실제로 큰 DNS 업체의 장애로 수많은 유명 사이트가 동시에 접속 불가가 된 적이 여러 번 있다. 캐시에 이미 저장된 주소는 한동안 계속 쓸 수 있다.

연결 맺기: 세 번의 악수

IP 주소를 알았으니 이제 서버와 TCP 연결(10장)을 맺는다. 전화를 걸어 “여보세요?” “네, 들려요.” “네, 저도 들려요.”라고 확인하듯, 세 번 신호를 주고받는다. 이를 3방향 핸드셰이크(3-way handshake)라 한다.

내 브라우저 웹 서버 ① SYN: 연결해도 될까요? ② SYN-ACK: 좋아요, 들려요 ③ ACK: 저도 들려요. 시작합시다
그림 11-2. TCP 연결에는 왕복 한 번 반의 시간이 든다. 서버가 멀수록 이 악수가 느려진다.

HTTPS: 엿듣지 못하게

10장에서 패킷이 수십 대의 라우터와 공유기를 거친다고 했다. 그 중 하나라도 나쁜 마음을 먹으면(예: 카페의 가짜 Wi-Fi) 내용을 몽땅 엿볼 수 있다. 비밀번호와 카드 번호가 그대로 보인다. 그래서 요즘 웹은 거의 모두 HTTPS를 쓴다. 마지막 S는 Secure(안전한)다. 내용을 암호화해서 브라우저와 서버만 읽을 수 있게 한다.

SIMULATOR

카페 Wi-Fi의 도청자 시점

연결 방식
내가 보낸 것
👀 도청자가 본 것
HTTPS에서도 도청자는 “어느 사이트(서버 IP)와 통신하는지”, “데이터 양”은 알 수 있다. 하지만 어떤 페이지를 보고 무엇을 입력했는지는 알 수 없다. 여기서 보이는 암호문은 설명을 위해 흉내 낸 것이다.
공개 정보로 같은 비밀 만들기

TLS 1.3의 대표적인 첫 연결에서는 브라우저와 서버가 각각 일회용 비밀값을 고르고, 그로부터 만든 공개 정보만 교환한다. 각자는 자기 비밀값과 상대의 공개 정보를 계산해 같은 공유 비밀을 얻는다(ECDHE 키 합의). 도청자는 공개 정보를 모두 보아도 공유 비밀을 쉽게 계산할 수 없다. 서버는 인증서와 서명으로 진짜 서버임을 증명하고, 양쪽은 공유 비밀에서 방향별 대칭 키를 만들어 대화를 암호화한다. 비밀 열쇠 자체를 상자에 넣어 보내는 예전 RSA 키 운반과는 다르다.

내 브라우저 은행 서버 ① 지원 방식 + 브라우저의 일회용 공개 정보 ② 서버 공개 정보 + 인증서·서명·완료 확인 ③ 인증서와 교환 내용의 서명 확인 → 공유 비밀에서 통신 키 도출 ④ 완료 확인 + 암호화한 요청 ⑤ 완료 확인 검사 후 요청 처리 ⑥ 방향별 대칭 키로 대화를 빠르게 암호화
그림 11-3. 인증서 기반 TLS 1.3 첫 연결의 대표적인 ECDHE 교환. 추가 협상이 없다면 TCP 연결 이후 한 번의 왕복으로 브라우저가 서버를 확인하고 암호화한 요청을 보낼 수 있다. 재개 연결과 PSK 방식은 흐름이 다르다.

그런데 도청자가 “내가 그 서버야”라며 가짜 공개 정보를 보내면 어떡할까? 서버는 인증 기관이 “이 인증용 공개 키는 example.com의 것”이라고 서명한 인증서와, 그에 대응하는 개인 키로 교환 내용에 서명한 증명을 보낸다. 브라우저 주소창의 보안 표시는 “암호화되어 있고, 인증서가 유효하다”는 뜻이다. 사이트가 착한 곳이라는 보증은 아니다. 피싱 사이트도 자기 도메인의 인증서를 받을 수 있으니 주소를 꼭 확인하자.

HTTP: 요청하고 응답받기

연결과 암호화가 준비되면 드디어 페이지를 요청한다. 웹의 대화 규칙이 HTTP(HyperText Transfer Protocol)다. 아래 HTTP/1.1 예시는 사람이 읽을 수 있는 텍스트 형식이다. HTTP/2와 HTTP/3는 같은 요청·응답 의미를 바이너리 프레임으로 실어 나른다.

// 브라우저 → 서버 (요청) GET /search?q=노트북 HTTP/1.1 Host: shop.example.com User-Agent: Mozilla/5.0 (...) Accept-Language: ko-KR Cookie: session=8f3a... // 서버 → 브라우저 (응답) HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 18342 Cache-Control: max-age=600 <!doctype html><html><head><title>검색 결과</title> ...

첫 줄의 GET은 “가져와 달라”는 뜻이다. 로그인 정보나 글을 보낼 때는 POST를 쓴다. 응답 첫 줄의 숫자는 상태 코드다.

코드뜻언제 보나
200 OK성공거의 모든 정상 응답
301 / 302다른 곳으로 이사 갔음http를 https로, 옛 주소를 새 주소로 보낼 때
304바뀐 것 없음, 캐시를 써라다시 방문했을 때
403권한 없음로그인하지 않고 비공개 페이지에 접근할 때
404그런 페이지 없음주소를 잘못 쳤거나 삭제된 글
500 / 503서버 내부 문제 / 과부하서버 프로그램 오류, 접속 폭주

HTML을 받은 브라우저는 그 안에 적힌 그림, 글꼴, 스타일(CSS), 프로그램(자바스크립트) 파일을 다시 요청한다. 요즘 뉴스 사이트 하나를 열면 이런 요청이 100개를 넘기도 한다. 그래서 하나의 연결로 여러 요청을 동시에 처리하는 HTTP/2, HTTP/3가 나왔다.

쿠키

HTTP는 원래 매 요청이 독립적이라 서버는 방금 로그인한 사람이 누구인지 기억하지 못한다. 그래서 서버는 응답에 작은 이름표(쿠키)를 실어 보내고, 브라우저는 다음 요청마다 그 이름표를 함께 보낸다. 위 요청의 Cookie: session=… 줄이 그것이다. 로그인이 유지되는 원리이자, 광고 추적에 쓰이는 원리이기도 하다.

글자에서 그림으로: 브라우저의 렌더링

서버가 보낸 HTML은 그냥 글자다. 브라우저는 이것을 다음 순서로 화면에 그린다.

  1. 파싱: HTML 글자를 읽어 <body> 안에 <h1>과 <p>가 있는 식의 나무 구조, 즉 DOM 트리를 만든다.
  2. 스타일 계산: CSS 규칙을 읽어 각 요소의 색, 글꼴, 크기를 정한다.
  3. 레이아웃: 화면 폭에 맞춰 각 상자의 위치와 크기를 계산한다. 글자가 몇 줄로 꺾일지도 여기서 정한다.
  4. 페인트·합성: 픽셀을 칠하고 여러 층을 합친다. 이 단계의 많은 부분을 GPU가 맡는다(12장).
HTML 글자 CSS 글자 DOM 트리 스타일 규칙 렌더 트리보일 것 + 모양 레이아웃위치·크기 페인트 합성GPU 글자 크기 하나만 바꿔도 레이아웃부터 다시 계산해야 한다.그래서 움직이는 효과는 레이아웃을 건드리지 않고 합성 단계(GPU)에서만 처리하는 것이 빠르다.
그림 11-4. 브라우저의 렌더링 파이프라인. 화면이 1초에 60번 바뀐다면 이 과정을 약 16 ms 안에 끝내야 한다.

왼쪽 HTML을 고쳐 보자. 오른쪽 화면과 아래 DOM 트리가 바로 바뀐다.

SIMULATOR

미니 브라우저: HTML → DOM → 화면

HTML (서버가 보낸 글자)
화면 (브라우저가 그린 결과)
해볼 것: <li>를 하나 더 추가하거나, style의 색을 바꿔 보자. 태그를 닫지 않아도 브라우저는 최대한 너그럽게 해석해 DOM을 만든다.

핵심 정리

  1. URL은 프로토콜 · 도메인 · (포트) · 경로 · 쿼리 · 조각으로 이루어진다.
  2. 페이지 로딩은 DNS → TCP 연결 → TLS(암호화) → HTTP 요청 → 응답 → 렌더링의 순서로 진행된다. 왕복 지연이 전체 시간을 크게 좌우한다.
  3. DNS는 루트 → 최상위 도메인 → 해당 도메인 서버 순으로 물어 이름을 IP 주소로 바꾸고, 결과를 캐시한다.
  4. HTTPS는 공개 키 암호로 비밀 열쇠를 나눠 대화를 암호화하고, 인증서로 서버가 진짜인지 확인한다.
  5. HTTP는 요청/응답 규칙이며, 상태 코드로 결과를 알린다. HTTP/1.1은 텍스트, HTTP/2·3은 바이너리 프레임을 쓴다.
  6. 브라우저는 HTML을 DOM 트리로 만들고 스타일 계산, 레이아웃, 페인트를 거쳐 화면을 그린다.

확인 퀴즈

DNS가 하는 일은?

사람이 기억하기 쉬운 이름(www.example.com)을 컴퓨터가 연결할 수 있는 IP 주소로 바꾸는 인터넷의 전화번호부다.

주소창의 자물쇠 아이콘이 보장하는 것은?

자물쇠는 암호화와 도메인 인증을 뜻한다. 피싱 사이트도 자기 도메인의 인증서를 받을 수 있으므로 주소를 확인해야 한다.

존재하지 않는 페이지를 요청했을 때 서버가 보내는 상태 코드는?

404 Not Found. 500은 서버 내부 오류, 301은 주소 이동, 200은 성공이다.

미국에 있는 서버의 페이지가 대역폭을 올려도 처음 뜨는 시간이 잘 줄지 않는 이유는?

여러 번의 왕복 × 긴 지연이 합쳐진다. 그래서 서버 복사본을 사용자 가까이에 두는 CDN이 효과적이다.