개발 학습 실습실

이 사이트의 실습은 자바스크립트를 켜야 움직입니다. 아래는 같은 내용을 글로 적은 것입니다.

공부 › 네트워크 › 큰 그림

주소 입력부터 응답까지

주소창에 입력하고 엔터를 누르면

브라우저가 주소 하나를 여는 동안 DNS 조회, TCP 연결, TLS 핸드셰이크, HTTP 요청, 리버스 프록시, 애플리케이션 서버, DB가 차례로 관여합니다. 어떤 단계는 캐시나 연결 재사용으로 건너뛸 수 있습니다.

일부만 실행으로 확인 · curl로 순서와 연결 재사용 확인, 프록시 뒤 구간은 미확인

이 실습에 나오는 개념

DNS
도메인 이름(example.com)을 컴퓨터가 통신에 사용하는 IP 주소로 바꿔 주는 시스템이다. 브라우저에 주소를 입력하면 먼저 DNS에 그 이름의 IP 주소를 물어본 뒤 해당 IP로 접속한다. 조회 결과는 일정 시간 동안 캐시된다.
웹 서버와 WAS
웹 서버는 HTTP 요청을 받아 이미지나 HTML 같은 정적인 파일을 응답하거나 요청을 다른 서버로 전달하는 프로그램이다(Nginx, Apache). WAS(웹 애플리케이션 서버)는 프로그램 코드를 실행해 요청마다 결과를 만들어 응답하는 프로그램이다(Tomcat). 웹 서버를 앞에 두고 WAS로 요청을 넘기는 구성이 흔하다.
리버스 프록시
클라이언트의 요청을 대신 받아 내부의 서버로 전달하고 그 응답을 클라이언트에 돌려주는 서버다. 클라이언트는 실제 서버를 직접 알지 못한다. 여러 서버로의 요청 분산, TLS 처리, 캐싱, 내부 서버 보호 등의 역할을 한다.
CDN
전 세계 여러 지역에 배치된 서버에 콘텐츠의 복사본을 두고, 사용자와 가까운 서버가 응답하게 하는 네트워크다. 이미지, 영상, 스크립트 같은 정적 파일의 전송이 빨라지고 원본 서버로 가는 요청이 줄어든다.
HTTPS와 TLS
HTTPS는 HTTP 통신을 TLS로 암호화한 것이다. TLS는 통신 내용을 제3자가 볼 수 없게 하고(기밀성), 중간에서 바꿀 수 없게 하며(무결성), 접속한 서버가 진짜인지 인증서로 확인한다(인증). SSL은 TLS의 전신인 프로토콜로, 지금은 폐기되어 실제로는 TLS만 쓰이지만 관습적으로 SSL이라는 이름이 함께 불린다.
3-way handshake
TCP 연결을 맺을 때 거치는 세 단계의 과정이다. 클라이언트가 연결 요청(SYN)을 보내고, 서버가 수락과 함께 자신의 연결 요청(SYN+ACK)을 보내며, 클라이언트가 이를 확인(ACK)한다. 양쪽이 서로 보내고 받을 수 있는 상태임을 확인한 뒤 데이터 전송을 시작한다.

이렇게 바꿔 보세요

처음 설정으로 실행하면

  1. 브라우저가 주소 https://shop.example/orders를 프로토콜(https), 호스트(shop.example), 경로로 나눕니다. https이므로 443번 포트로 접속할 것입니다.
  2. shop.example의 IP 주소를 모릅니다. DNS 서버에 물어 IP 주소를 받아 옵니다. 결과는 정해진 시간(TTL) 동안 캐시에 보관됩니다.
  3. 그 IP의 443번 포트로 TCP 연결을 맺습니다(3-way handshake). 서버까지 한 번 왕복하는 시간이 듭니다.
  4. TLS 핸드셰이크로 서버의 인증서를 확인하고 암호화 키를 합의합니다. 한 번 더 왕복합니다.
  5. 암호화된 연결 위로 HTTP 요청을 보냅니다. 요청 줄, 헤더(Host, 쿠키, User-Agent 등)가 서버로 갑니다.
  6. 가장 먼저 요청을 받는 것은 nginx입니다. TLS를 풀고, 경로를 보고 어디서 처리할지 정합니다.
  7. nginx가 요청을 뒤쪽의 톰캣(8080 포트)으로 넘깁니다. 톰캣이 스레드 풀에서 스레드 하나를 배정하고, 필터를 거쳐 스프링의 DispatcherServlet으로 전달합니다.
  8. DispatcherServlet이 /orders를 처리할 컨트롤러를 찾아 실행합니다. 컨트롤러는 서비스를, 서비스는 리포지토리를 호출합니다.
  9. 커넥션 풀에서 커넥션을 빌려 SQL을 실행하고 결과를 받습니다. 서버 안에서 쓰는 시간 가운데 가장 큰 부분입니다.
  10. 조회 결과를 JSON이나 HTML로 바꿔 응답을 만듭니다. 응답은 톰캣, nginx를 거쳐 되돌아갑니다.
  11. 응답이 브라우저에 도착합니다. HTML이라면 브라우저가 해석하면서 그 안의 CSS, 스크립트, 이미지 주소를 발견하고, 그것들에 대해 같은 과정을 반복합니다.

실행 결과

코드

# nginx (리버스 프록시)
server {
    listen 443 ssl;
    server_name shop.example;

    location /static/ {                  # 정적 파일은 직접 응답
        root /var/www;
    }
    location / {                         # 나머지는 애플리케이션 서버로 전달
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
}

이 모형의 전제

시간은 상대적인 크기를 보이기 위한 예시입니다(서버까지 한 번 가는 데 30ms, CDN은 5ms, DNS 조회 40ms, DB 조회 20ms). 실제 값은 거리와 네트워크, 쿼리에 따라 크게 다릅니다. 구성은 nginx가 앞에서 TLS를 처리하고 뒤의 스프링 부트(내장 톰캣)로 넘기는 흔한 형태를 가정했습니다. 단계가 실제로 이 순서로 일어나고 연결을 재사용하면 앞의 세 단계가 사라진다는 점은 curl로 공개 사이트에 연달아 두 번 요청해 확인했습니다. 첫 요청은 DNS 조회 27ms, TCP 연결 완료 60ms, TLS 완료 156ms, 첫 바이트 194ms였고, 같은 연결로 보낸 두 번째 요청은 DNS·TCP·TLS가 0이고 전체 40ms였습니다. 리버스 프록시 뒤의 구간은 직접 확인하지 못했습니다.

다음 실습: 계층 구조와 캡슐화

이 실습에 나오는 개념

이 실습에서 보는 것

설정

코드


      
    

그림

실행 비교

이렇게 바꿔 보세요