인터넷은 어떻게 작동하는가
계층화된 프로토콜과 인프라를 통해 인터넷이 클라이언트와 서버를 어떻게 연결하는지에 대한 정신적 모델을 구축하세요
큰 그림: 요청 생명주기
요청은 아래로 이동합니다.
사용자 의도 형성
- 인터넷 요청 생명주기는 순서대로 동작하는 전문화된 계층들의 조정된 시퀀스입니다.
- 각 계층은 서로 다른 시스템 문제를 해결하고 다음 계층에 책임을 넘깁니다.
- 하나의 동작처럼 느껴지는 것은 실제로는 여러 추상화 계층을 가로질러 실행되는 구조화된 파이프라인입니다.
상세정보
브라우저 → DNS → TCP → HTTP → 서버 → 데이터베이스 → 응답 → 렌더링
높은 수준에서 보면, 웹 요청은 하나의 동작이 아니라 함께 작동하는 시스템들의 체인입니다. 각 단계는 목적지를 찾고, 통신을 설정하고, 요청을 정의하고, 로직을 처리하고, 데이터를 가져오고, 결과를 반환하는 등 특정한 문제 하나를 해결하기 위해 존재합니다.
DNS는 *“이 서비스는 어디에 있나요?”*에 답하고, TCP는 *“어떻게 안정적으로 통신하나요?”*에 답하며, HTTP는 *“정확히 무엇이 요청되었나요?”*에 답합니다. 서버와 데이터베이스는 *“시스템이 무엇을 계산하고 반환해야 하나요?”*에 답합니다.
이 계층들은 독립적으로 동작하지만 순서대로 협력합니다. 어떤 단일 구성 요소도 전체 시스템을 이해하지는 못하며, 각자 자신의 역할을 수행한 뒤 다음 단계로 제어를 넘깁니다.
사용자에게는 즉시 일어나는 것처럼 느껴지지만, 실제로는 밀리초 단위로 실행되는 추상화의 구조화된 파이프라인입니다.
트리거: URL 입력
사람은 이름을 입력합니다. 네트워크는 숫자 라우팅 식별자를 필요로 합니다.
- URL은 직접적인 네트워크 주소가 아니라 사용자 친화적인 레이블입니다.
- 브라우저는 도메인을 추출하고 해석을 위해 준비합니다.
- 통신을 시작하기 전에 도메인은 IP 주소로 변환되어야 합니다.
상세정보
사용자가 URL을 입력하면 브라우저는 단순히 “페이지를 여는” 것 이상의 일을 합니다. 먼저 입력을 분석하여 프로토콜(예: HTTPS), 도메인 이름, 요청된 경로를 식별합니다.
컴퓨터는 example.com 같은 도메인 이름을 사용해 트래픽을 라우팅할 수 없습니다. 네트워크는 숫자로 된 식별자인 IP 주소를 사용합니다.
브라우저는 로컬 캐시를 확인하여 해당 도메인의 IP 주소를 이미 알고 있는지 살펴봅니다. 그렇지 않다면, 이름을 라우팅 가능한 IP 주소로 해석하기 위해 DNS 조회 과정을 시작합니다.
이 변환 단계가 끝나야만 시스템은 연결을 설정하는 다음 단계로 진행할 수 있습니다.
이름에서 IP로: DNS 해석
DNS는 계층적이고 전 세계에 분산된 조회 시스템을 통해 사람이 읽을 수 있는 도메인 이름을 IP 주소로 변환합니다.
캐시 적중: 즉시. 캐시 미스: 전체 DNS 계층을 순회.
- DNS는 웹사이트 이름을 컴퓨터가 통신에 사용하는 숫자 형태의 IP 주소로 바꿉니다.
- 조회는 올바른 주소를 찾을 때까지 여러 DNS 서버를 거치는 단계별 경로를 따릅니다.
상세정보
DNS는 인터넷을 위한 분산 디렉터리로 설계되었습니다. 하나의 중앙 데이터베이스에 의존하는 대신, 전 세계 규모를 지원하기 위해 책임이 여러 서버 계층에 나뉘어 있습니다.
도메인이 로컬에 아직 알려져 있지 않으면, 재귀 리졸버가 조회 과정을 시작합니다. 먼저 루트 서버에 연결하고, 루트 서버는 .com 또는 .org 같은 올바른 최상위 도메인(Top-Level Domain, TLD) 서버를 알려줍니다. 그런 다음 TLD 서버는 해당 도메인에 대한 권한 있는 네임 서버로 리졸버를 안내합니다.
권한 있는 서버가 최종 IP 주소를 제공합니다. 그 주소는 클라이언트로 반환되며, 브라우저는 다음 단계로 진행해 올바른 대상과 네트워크 연결을 설정할 수 있습니다.
이러한 계층적 설계는 DNS를 체계적으로 유지하고, 확장 가능하게 만들며, 매일 수십억 건의 조회를 지원할 수 있게 합니다.
연결: TCP 핸드셰이크
신뢰할 수 있는 통신은 양쪽이 대화가 어떻게 진행될지에 대해 합의한 뒤에야 시작됩니다.
클라이언트
서버
클라이언트: 동기화합시다!
- TCP는 데이터가 신뢰성 있게 그리고 올바른 순서로 도착하도록 보장합니다.
- 데이터를 보내기 전에 양쪽은 3단계 핸드셰이크를 수행합니다.
- 이 핸드셰이크는 준비 상태를 확인하고 시퀀스 번호를 동기화합니다.
상세정보
TCP는 애플리케이션 데이터를 즉시 보내기 시작하지 않습니다. 먼저 SYN → SYN-ACK → ACK의 3단계 과정을 사용해 연결을 설정합니다.
클라이언트는 먼저 연결을 요청하기 위해 SYN(synchronize) 메시지를 보냅니다. 서버는 SYN-ACK로 응답하여 요청을 확인하고 자신의 시작 시퀀스 번호를 공유합니다. 그런 다음 클라이언트는 ACK를 보내 수신을 확인합니다. 이 시점에서 양쪽은 초기 시퀀스 번호에 합의했고, 상대방이 준비되었다는 것도 알게 됩니다.
이 교환 과정은 신뢰할 수 있는 전달의 기반을 마련합니다. TCP는 시퀀스 번호를 추적하고, 손실된 패킷을 감지하며, 누락된 데이터를 재전송하고, 네트워크 상태에 따라 전송 속도를 조정합니다.
이러한 조정 단계가 끝난 뒤에야 실제 애플리케이션 데이터가 흐르기 시작합니다.
애플리케이션 계층: HTTP
HTTP는 클라이언트가 리소스를 요청하는 방식과 서버가 구조화된 요청-응답 프로토콜을 통해 응답하는 방식을 정의합니다.
- HTTP는 브라우저와 서버가 모두 따르기로 합의한 공통 언어를 정의합니다.
- 리소스를 요청하는 방식과 응답이 형식화되는 방식을 표준화합니다.
- 원시 네트워크 데이터를 “이 페이지를 가져와라” 또는 “이 폼을 제출하라”와 같은 의미 있는 동작으로 바꿉니다.
상세정보
TCP는 바이트를 신뢰성 있게 전달하지만, 그 바이트가 무엇을 의미하는지는 정의하지 않습니다. HTTP는 TCP 위에 위치하며 통신에 구조와 의미를 부여합니다. 클라이언트가 무엇인가를 요청하는 방식과 서버가 응답하는 방식을 정의합니다.
HTTP 요청에는 메서드(GET 또는 POST 같은 것), 메타데이터를 설명하는 헤더, 그리고 선택적으로 데이터를 담는 본문이 포함됩니다. 서버는 상태 코드, 헤더, 그리고 요청된 콘텐츠로 응답합니다. 양쪽이 같은 규칙을 따르기 때문에 메시지를 일관되게 해석할 수 있습니다.
인터넷은 공유 시스템이기 때문에 HTTP는 필수적입니다. 메시지 구조와 의도를 정의하는 공통 프로토콜이 없다면 브라우저와 서버는 서로를 이해하지 못할 것입니다. HTTP는 웹을 위한 그 공통 언어를 만듭니다.
HTTP는 데이터가 네트워크를 통해 물리적으로 어떻게 이동하는지가 아니라, 무엇이 요청되고 무엇이 반환되는지를 정의합니다.
서버 내부
서버는 운영 체제가 하드웨어 리소스를 관리하고 애플리케이션 코드가 요청을 처리하고 응답하기 때문에 동작합니다.
들어오는 요청
OS가 CPU + 메모리를 할당 → 앱이 로직을 실행
응답 전송됨
- 클라이언트 요청이 도착하면 운영 체제를 통해 서버 프로그램으로 전달됩니다.
- 운영 체제는 해당 요청을 처리하기 위해 CPU 시간, 메모리, 네트워크 접근을 할당합니다.
- 서버 애플리케이션은 로직을 실행하고 다시 보낼 응답을 생성합니다.
상세정보
데이터가 머신에 도달한다고 해서 자동으로 “실행”되는 것은 아닙니다. 운영 체제는 네트워크 데이터를 수신하고 소켓을 사용해 올바른 프로세스로 전달합니다. 이렇게 요청이 서버 프로그램에 도달합니다.
그다음 OS가 필요한 리소스를 관리합니다. 서버가 실행할 수 있도록 CPU 시간을 스케줄링하고, 처리에 필요한 메모리를 할당하며, 파일이나 데이터베이스에 대한 접근을 제어합니다. 운영 체제가 이러한 리소스를 조정하지 않으면 여러 요청을 안전하고 효율적으로 처리할 수 없습니다.
요청이 서버 프로세스 안으로 들어오면 애플리케이션 로직이 이를 처리합니다. HTTP 메시지를 해석하고, 필요한 계산이나 데이터베이스 조회를 수행한 뒤, 응답을 구성합니다.
운영 체제는 실행을 가능하게 하고, 서버 애플리케이션은 동작을 정의합니다.
데이터베이스 및 영속성
데이터베이스는 애플리케이션 데이터를 시간이 지나도 저장하고, 정리하고, 안정적으로 검색할 수 있도록 설계된 시스템입니다.
| ID | 이름 | 역할 |
|---|---|---|
| 21 | Alice | User |
| 22 | Brian | Admin |
| 23 | Cathy | User |
| 24 | Daniel | User |
| 25 | Eva | Admin |
- 데이터베이스는 단일 프로그램 실행을 넘어 데이터를 영구적으로 저장하기 위해 존재합니다.
- 데이터를 효율적으로 검색하고 업데이트할 수 있도록 정보를 구조화합니다.
상세정보
애플리케이션은 사용자 계정, 게시물, 거래, 로그, 설정 등 데이터를 끊임없이 생성합니다. 이 데이터가 메모리에만 있다면 프로그램이 재시작될 때마다 사라집니다. 데이터베이스는 디스크나 분산 시스템에 영속적인 저장소를 제공함으로써 이 문제를 해결합니다.
하지만 저장만으로는 충분하지 않습니다. 데이터는 구조화되어 있어야 하고, 조회 가능해야 합니다. 데이터베이스는 정보를 테이블이나 컬렉션으로 정리하고, 애플리케이션이 모든 데이터를 수동으로 훑지 않고도 특정 레코드를 가져올 수 있게 하는 쿼리 언어를 제공합니다.
성능을 개선하기 위해 데이터베이스는 인덱스를 사용합니다. 인덱스는 조회 맵처럼 동작하는 특수한 데이터 구조입니다. 모든 행을 확인하는 대신, 엔진은 관련 항목으로 바로 이동할 수 있습니다.
데이터베이스가 중요한 이유는 현대 애플리케이션이 지속적인 상태를 필요로 하기 때문입니다. 데이터베이스가 없으면 모든 요청은 이전 활동에 대한 기억 없이 독립적으로만 처리됩니다.
성능 계층: 캐싱과 CDN
현대 시스템은 자주 요청되는 콘텐츠를 매번 다시 계산하는 대신 사용자에게 더 가까운 곳에 저장하여 속도를 향상시킵니다.
- 캐싱은 저장된 응답을 제공하여 반복 계산을 피합니다.
- CDN은 콘텐츠를 지리적으로 분산하여 지연 시간과 오리진 부하를 줄입니다.
상세정보
사용자가 같은 리소스를 여러 번 요청할 때마다 처음부터 다시 계산하는 것은 비효율적입니다. 캐싱은 응답의 복사본을 저장해 두었다가, 이후 요청을 데이터베이스나 애플리케이션 로직을 다시 거치지 않고 즉시 처리할 수 있게 해줍니다.
캐시는 브라우저 내부, 서버, 네트워크 엣지 등 여러 계층에 존재합니다. 콘텐츠 전송 네트워크(Content Delivery Network, CDN)는 이 개념을 전 세계로 확장하여 지리적으로 분산된 데이터 센터에 콘텐츠를 배포합니다. 사용자는 항상 오리진 서버에 접속하는 대신 가장 가까운 엣지 위치로 라우팅됩니다.
물리적 거리를 줄이면 네트워크 지연 시간이 낮아지고, 반복 계산을 줄이면 서버 부하가 감소합니다. 이 두 가지 최적화는 함께 대규모 환경에서 응답 시간을 크게 개선합니다.
하지만 캐시된 데이터는 오래될 수 있으므로, 시스템은 속도와 데이터 최신성 사이의 균형을 맞춰야 합니다.
실패 지점
계층형 시스템에서는 경로상의 어떤 구성 요소든 실패할 수 있으며, 전체 경험은 시스템이 이러한 실패를 얼마나 잘 처리하느냐에 따라 달라집니다.
DNS
TCP
서버
데이터베이스
- 요청 생명주기의 모든 계층은 서로 독립적으로 실패할 수 있습니다.
- 한 구성 요소의 실패가 전체 요청의 완료를 막을 수 있습니다.
- 신뢰할 수 있는 시스템은 부분 실패를 예상하고 복구합니다.
상세정보
인터넷 요청 생명주기는 DNS, 전송, 서버, 데이터베이스를 아우르기 때문에, 문제는 어느 단계에서든 발생할 수 있습니다. DNS가 도메인을 해석하지 못하면 연결은 시작되지 않습니다. 네트워크가 패킷을 드롭하거나 TCP 연결이 끊기면 통신이 중단됩니다.
요청이 서버에 도달한 뒤에도 실패는 계속 발생할 수 있습니다. 서버 프로세스가 충돌하거나, 메모리가 부족해지거나, 데이터베이스에 연결하지 못할 수 있습니다. 느리거나 응답하지 않는 데이터베이스는 전체 응답을 지연시킬 수 있습니다.
분산 시스템은 한 번에 모두 실패하는 경우가 드뭅니다. 대신 한 지역, 한 인스턴스, 또는 한 의존성씩 부분적으로 실패합니다. 복원력 있는 시스템을 설계하려면 여러 계층에 걸쳐 중복성, 상태 확인, 재시도, 그리고 대체 메커니즘을 추가해야 합니다.
실패가 어디에서 발생할 수 있는지 이해하는 것은 실제 시스템이 어떻게 동작하는지 이해하는 데 필수적입니다.
질문 섹션
1 / 5