브라우저 - 웹 서버가 URL 리소스를 처리하는 과정


  • [ 배경 ]
    • 웹 개발을 하던 중 브라우저에 URL을 입력하면 웹 서버에 Http 통신으로 패킷을 보내고 웹 서버에서는 해당 패킷을 분석해 DB나 다른 캐시 서버의 데이터를 조회하여 필요한 데이터를 처리 후 Response 패킷을 브라우저에게 전송한다 정도의 개념은 알고 있었습니다.

    • 문득 실제 브라우저가 url을 어떻게 처리하는지, dns서버에선 어떤 알고리즘으로 IP를 Domain Name으로 변경하는지, Http 통신과 Https 통신의 차이점은 어느 부분에서 일어나는지, TCP 통신을 위해 소켓은 어디에서 생성하는지, Httpd가 무엇인지, 웹서버, WAS가 무엇인지 Spring의 처리 순서는 무엇인지, 웹 엔진이 html, script, css 데이터는 어떻게 처리하여 렌더 하는지 등등 궁금하여 정리하게 되었습니다.

  • [ 과정 ]
    1. 주소표시줄에 url 입력하고 enter 입력한다.
    2. 브라우저가 url 해석한다. 정상적이지 않다면 기본 검색 엔진으로 검색을 요청한다.
    3. url 문법이 맞다면 encoding(숫자는 문자를 처리하는 방법) url host 부분에 적용한다.
    4. HSTS(HTTP Strict Transport Security) 보안 기능목록을 로드해서 확인한다.
    5. DNS(Domain Name Server) 조회한다.
    6. 라우터에게 ARP(Address Resolution Protocol) 통신하여 대상의 ip mac address 알아낸다.
    7. 대상 tcp 통신을 통해 Socket 연다. (3-hand-sake) syn+ack 만약 연결이 안 되면 다시 대기한다.
    8. HTTPS 경우 TLS(Transport Layer Securiy) handshake 추가된다.
    9. HTTP 프로토콜을 사용해 웹서버에게 요청한다.
    10. 정적 데이터는 HTTP 웹서버(아파치, IIS 등) 서버가 응답한다.
    11. 동적 데이터는 톰캣(WAS)이 응답하여 리스너를 등록하고 서블릿 콘텍스트를 생성 후에 클래스로더리스너에서 이벤트를 받으면 ServeleContext를 생성하고 필터를 등록하고 DispatcherServlet를 처리한다.
    12. Spring에서 DispatcherServelet의 요청을 controller - servcie - DAO(ex.mybatis, hibernate), DTO - controller - DispatcherServelet - 브라우저 Response 순으로 전송한다. 
    13.   브라우저가 엔진을 이용하여 랜더 한다.

  • 각 단계별로 상세히 알아보겠습니다.
    • 1. 주소표시줄에 url 입력하고 enter 입력한다.
      • URL 은 Uniform Resource Locator로 웹에서 정해진 유일한 자원이며 HTML, CSS, 이미지 등이 될 수 있습니다. URL에 의해 표현된 자원과 URL 자체는 웹서버에 의해 처리됩니다.
      • URL 구조 http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
        • Protocol(프로토콜): http 웹 통신 규약으로 컴퓨터 네트워크에서 데이터를 교환하거나 전송하기 위한 방법들입니다. 이외에 ftp, mailto가 있습니다.
        • Domain Name(도메인명): www.example.com 어떤 웹서버가 요구되는 것인지를 가리킵니다. 대안으로는 IP address를 사용하기도 합니다. 
        • Port(포트): :80 웹서버에서 자원을 접근하기 위해 사용하는 관문(gate)을 뜻합니다. 웹서버가 자원을 접근하기 위해 표준 HTTP 포트를 사용한다면 보통 생략이 가능합니다
        • PathResource(자원 경로): /path/to/myfile.html 웹서버에서 자원에 대한 경로입니다. 물리적 파일 위치 또는 추상화된 경로를 나타냅니다.
        • Parameters(파라미터)?key1=value1&key2=value2 파라미터들은 &기호로 구분하여 키/값 쌍을 이룹니다. 웹서버는 자원을 반환하기 전에 추가적인 작업을 위해 파라미터를 사용합니다.
        • Anchor(닻): #SomewhereInTheDocument 자원 안에서의 "bookmark"입니다. 즉 Anchor 지점에 위치된 내용을 보여주기 위해 브라우저에게 방향을 알려줍니다. 예를 들어 HTML 문서에서 브라우저는 anchor가 정의한 곳의 점을 스크롤합니다. 다른 말로는 부분 식별자 (fragment identifier)라고 합니다.
      • 그 외
    • 2. 웹 브라우저가 url 해석한다. 만약 url 문법에 맞지 않는다면 웹브라우저가 기본 검색 엔진으로 검색을 요청한다.
      • 브라우저는 1번에서 알아본 url 구조가 맞는지 확인합니다. 만약 맞지 않다면 '기본 검색 엔진'으로 검색을 웹서버에 요청합니다.
      • 기본 검색 엔진 예시로는 크롬 설정에 검색어의 패턴을 설정할 수 있습니다. URL(검색어 자리에 % S 입력)

검색 엔진 예시

  • 3. url 문법이 맞다면 encoding(숫자는 문자를 처리하는 방법) url host 부분에 적용한다.

URL Encoding

  • 4. HSTS(HTTP Strict Transport Security) 보안 기능 목록을 로드해서 확인한다.
    • (HTTP 대신 HTTPS) 사용하는지 확인하는 과정으로 HSTS를 강제하게 될 때 서버 측에서 302 Redirect를 이용하여 전환시켜줄 수 있습니다. 하지만 이것이 취약점의 포인트로 작용될 수도 있습니다. 따라서 사용자가 최초로 사이트에 접속 시도를 하게 되면 웹서버는 SSL(Secure Socket Layer)을 이용하여 브라우저에게 응답하게 됩니다. 즉, https 접속을 강제합니다.

  • 브라우저는 이응답을 근거로 일정 시간 (max-age) 동안 HSTS 응답을 받은 웹사이트에 대해서 https 접속을 판단할 수 있습니다. 이렇게 설정된 HSTS내역은 브라우저에서 확인할 수 있습니다. 

max-age=0; 일 경우 Strict-Transport-Security 헤더가 비활성화 되어 HTTP를 통한 접근이 허용된다.

  • 5. DNS(Domain Name Server) 조회한다.
    • 1) DNS에 요청 보내기 전 브라우저는 해당 Domain에 Cache 데이터가 있는지 확인합니다.
      • 크롬의 경우 chrome://net-internals/#dns에서 확인 가능

    • 2) 없을 경우 로컬에 저장돼 있는 hosts 파일에서 참조할 수 있는 Domain이 있는지 확인합니다.

C:\Windows\System32\drivers\etc\hosts

    • 3) 1),2)가 전부 없을 경우 Network stack에 구성돼 있는 DNS로 요청을 보냅니다.
      네트워크 스택이 궁금하신 분은 여기를 참조 부탁드립니다.
      (일반적으로 DNS는 Local, router, ISP(인터넷 서비스 제공자, KT, LG, SK업체)의 캐싱 DNS으로 이루어져 있습니다.)

  • 6. 라우터에게 ARP(Address Resolution Protocol) 통신하여 대상의 ip mac address 알아낸다.
    • ARP broadcast를 보내려면 Network stack library가 조회할 대상의 IP, Mac Address를 알아야 합니다.

    • ARP는 주소 결정 프로토콜로 네트워크 상의 IP주소를 물리적 네트워크로 대응(bind) 하기 위한 규약입니다.

    • Mac Address는 Media Access Control의 약자로 네트워크 카드 하드웨어에 부여되는 고유한 물리 주소입니다.

    • ARP cache는 대상 ip에 대한 ARP 항목을 확인하여 cache가 있다면 mac주소를 반환합니다.
      • 1) ARP cache가 없는 경우 대상 IP주소에 local subnet에 있는지 routing table을 조회합니다.
      • 2) 있다면 subnet과 연관된 interface 사용을 사용하고
      • 3) 없다면 기본 gateway의 subnet과 연관된 interface를 사용합니다.
      • 4) Network libray는 Link Layer(OSI Model 2 계층)에 ARP 통신을 요청합니다.

      • 5) 응답에서 target MAC Address와 IP Address로 DNS 프로세스를 다시 시작합니다.
      • 6)  DNS에 53번 포트를 열어 UDP 또는 TCP를 요청을 합니다. (응답 데이터의 크기에 따라 다름)
      • 7) 로컬 / ISP DNS가 없는 경우 SOA(Service-oriented architecture)에 도달하기까지 재귀 요청으로 보내서 응답을 받습니다.
        • SOA란 기존의 애플리케이션의 기능들을 비즈니스적인 의미를 가지는 기능 단위로 묶어 표준화된 인터페이스를 통해 서비스로 구현하고, 이 서비스들을 기업의 업무에 따라 조합 구성하는 소프트웨어 아키텍처로 자세한 건 여길 참조 부탁드립니다.

인터넷 서비스인 WWW 흐름도, IP 정보를 바탕으로 Ethernet 물리주소인 MacAddress에 접근 후 통신

 

  • 7. 대상 tcp 통신을 통해 Socket 엽니다.
    • HTTP의 경우 TCP 통신 (3-hand-sake) syn, ack 만약 연결이 안 되면 다시 대기합니다.

 

 

  • 8. HTTPS 경우 TLS(Transport Layer Securiy) handshake 추가된다.

  • HTTP의 취약점인 패킷의 메시지 내용이 그대로 보이는 것을 방지하기 위해
    메시지 암호화를 하는 과정입니다. 
    • 증명서를 통해 서버 또는 클라이언트의 신원을 확인하고, 데이터를 암호화, 인증, 안정성을 보장해줍니다.
    • HTTP 통신 소켓 연결 부분을 SSL Layer로 대체하여 성능은 조금 느리지만, 보안이 중요해져 세계적으로 HTTPS 사용을 권장하고 있습니다.
    • 사용 목적은 신뢰할 수 있는 사이트인지 보장하기 위해서입니다.
    • 암호화 방식에는 대칭키, 공개키 암호화, 디지털 서명 등의 방식이 있습니다.

  • 9. HTTP 프로토콜을 요청한다.
    • Client가 HTTP 프로토콜을 사용해서 서버에 다음과 같은 형식으로 요청을 보낸다.

HTTP 요청

 

  • 10. 정적 데이터는 HTTP 웹서버(아파치, IIS 등) 서버가 응답합니다.
    • HTTPD(HTTP daemon) 서버는 Linux의 경우 Apache 또는 Nginx이고 Windows의 경우 IIS이다.
      • HTTPD 응답 순서는 아래와 같습니다.
        • 1) HTTPD 서버가 요청을 수신합니다.
        • 2) 서버는 요청을 다음 매개변수로 구분합니다 ( HTTP method, GET, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, HEAD...) 단순 검색의 경우 GET
        • 3) 서버는 google.com에 해당하는 서버에 구성된 가상 호스트(IP나 도메인명을 여러 개 구성)가 있는지 확인합니다.
        • 4) 서버는 google.come의 HTTP Method(GET 요청)이 클라이언트(브라우저)의 IP, 인증 등을 통해 method를 사용 가능한지 확인합니다.
        • 5) 서버에 rewrite module이 설치되어 있으면 요청된 rule 중 하나와 일치하도록 시도 없으면 rule을 사용하여 요청을 다시 작성합니다. ( ex) Apache경우 mode_rewrite, IIS 경우 URL Rewrite)
        • 6) 서버는 요청에 해당하는 콘텐츠를 가져오고 index파일을 분석합니다.
        • 7) 서버는 핸들러(요청에 응답을 처리할 함수)에 따라 파일 구문을 분석합니다.
        • 8) index 파일을 분석 후 출력을 하기 위해 브라우저에게 Response 패킷을 전송합니다.

 

  • 11. 동적 데이터는 톰캣(WAS)이 처리합니다. 처리 순서는 아래와 같습니다.
    • 1) tomcat(WAS)이 webxml을 읽어서 Listener(ClassLoaderListener)를 등록합니다.
    • 2) Web Applicaiton Server가 Servlet Context를 생성하면 Servlet Context 초기화 이벤트가 발생하고, 이벤트를 ClassLoaderListener가 이벤트를 받아서 contextInitialized()를 실행합니다.
    • 3) context를 생성합니다. (XmlWebApplicationContext)
    • 4) context가 active인지 root인지 확인합니다. root이면 parent가 없습니다.
    • 5) ServletContext를 WebApplicationContext의 servlet context로 설정합니다.
    • 6) contextConfigLocation 설정 파일 위치를 읽어 StandardServletEnvironment를 생성합니다.
    • 7) 내부적으로 StandardEnvironment를 확장하고 내부적으로는 AbstractEnvironmnet를 확장합니다.
      • property source customize
      • init
      • refresh
    • 8) Filter를 등록합니다 ( StandardServletEnvironment를 다시 customize 하면서 property soruce 설정)
    • 9) DispatcherServlet을 등록합니다. ( ServletContext 생성 )

 

  • 12. Spring이 DispatcherServlet을 처리합니다. 순서는 아래와 같습니다.
    • 1) DispatcherServelet이 요청 내용을 가로챕니다.
    • 2) DispatcherServelet이 HandlerMapping에게 해당 요청을 매핑한 컨트롤러가 있는지 물어봅니다.
    • 3) 요청에 매핑한 컨트롤러가 있다면 @RequestMapping을 통하여 처리할 메서드에 도달합니다.
    • 4) 컨트롤러에서는 해당 요청을 처리할 Service를 주입(DI) 받아 비즈니스 로직 Service에게 위임합니다.
    • 5) Service에서는 요청에 필요한 작업 대부분을 담당하여 데이터베이스에 접근이 필요하면 DAO를 주입받아 DB 처리를 하는 DAO에게 작업을 위임합니다.
    • 6) DAO는 mybats 또는 hibernate 등 ORM 설정을 이용하여 SQL 쿼리를 DB에 전송하여 원하는 정보를 처리 후 서비스에게 다시 돌려줍니다. (이때, 보통 Request와 함께 날아온 DTO(@RequestParam, @RequestBody 등)으로부터 결과로 받은 Entity 객체를 Response에 필요한 DTO로 변환합니다.)
      • db connection pool
        • Was가 실행되면서 DB와 미리 연결해놓은 객체들을 pool에 저장해두었다가 클라 요청이 오면 빌려주고 처리가 완료되면 반납해줍니다.
      • db query optimization index
        • JPA 환경에서 Optimizer의 index type을 APM으로 성능 분석해 index 방식을 확인합니다.
          Composite Primary Key의 쿼리 서술 방식을 변경하여 성능을 튜닝합니다.
    • 7) 모든 비즈니스 로직을 끝낸 서비스가 결과물을 컨트로러에게 회신합니다.
    • 8) 결과물을 받은 컨트롤러는 Model 객체에 결과를 넣거나, 어떤 view(jsp) 파일을 보여줄 것인지 정보를 DispatcherServelet에게 보냅니다.
    • 9) DispatcherServelet은 ViewResolver에게 받은 뷰 정보를 전달합니다.
    • 10) ViewResolver는 해당 jsp 찾아서 응답할 View를 DispatcherServelet에게 알려줍니다.
    • 11) DispatcherServelet은 응답할 View에게 Render를 지시하고 View는 응답 로직을 처리합니다.
    • 12) 결과적으로 DispatcherServelet이 브라우저에게 렌더링 할 View를 전송합니다.

  • *DataSource, Connetion Pool
    • Datasource란 jdbc로 데이터베이스에 접근하면, 접근할 때마다 connection을 맺고 끊는 작업을 합니다. 이 네트워크 비용이 적지 않기 때문에 Connection Pool을 생성해두고 db에 접근할 때 사용자에게 미리 생성된 conneciton을 제공한다.
      spring-boot의 경우 내장 was로 프로그램마다 Datasource 가지고 connection 관리한다면 비효율적이다. WAS 내에서 connection을 관리하는 게 효율적이다. 
  • db동작 순서
    • 사용한 dbms인 mysql의 동작 순서는 대략적으로 아래와 같다.
      • 쿼리 구문분석
      • 표준화( 주석이나 공백 제거)
      • 최적화 (쿼리 분석, 제한자, 조인 조건, 인덱스 선택, 조인 처리)
      • 컴파일( 쿼리 파일 이진 코드 생성 )
      • 실행 ( 액세스 엔진이 처리 후 Application에 회신 )
  •  13. 웹 브라우저가 랜더 한다.
    • 서버가 리소스 (HTML, CSS, Javascirpt, Image 등)을 브라우저에게 제공하면 브라우저는 아래 순서와 같이 처리합니다.
      • 1) 구문 분석 ( HTML, CSS , Javascirpt )
      • 2) 렌더링을 위한 Dom Tree 구성
      • 3) 렌더 트리 구성
      • 4) 렌더 트리 레이아웃 배치
      • 5) 렌더 트리 출력(브라우저에 출력)
    •  *Javascript를 보통 html 구문 아래에 두는 이유
      1. HTML을 읽는 과정에 스크립트를 만나면 중단 시점이 생기고 그만큼 Display에 표시되는 것이 지연된다.
      2. DOM 트리가 생성되기 전에 자바스크립트가 생성되지도 않은 DOM의 조작을 시도할 수 있다.

    • 웹 브라우저의 구조(BOM, DOM)와 HTML CSS parsing, Paging Rendering, GPU Rendering 등의 내용은 간단한 내용이 아니기 때문에 다른 블로그 글에서 정리하려고 합니다.
  • 기타 인프라 구성
    • 대용량 처리를 위해 ( 웹캐시 서버, 프락시 서버(방화벽, LB ) , 게이트웨이 서버 ,  ) 같은 인프라 구성 서버가 필요합니다.
      • 웹 캐시 서버
        • 정적 콘텐츠(JS, CSS, 이미지) 등을 특정 위치(client, network, CDN 등)에 저장하여, 웹사이트 서버에 해당 콘텐츠를 매번 요청받는 것이 아닌 캐싱하여 불러옴으로써 응답 시간을 줄이고, 서버 트래픽을 감소시킬 수 있습니다.
      •  프락시 서버
        • HTTP protocol 관점에서 말하자면 서버와 클라이언트 사이에 위치하며, 클라이언트의 모든 HTTP 요청을 받아 서버에 전달합니다. 프락시 서버는 보안(방화벽)을 위해 사용하고, 요청,응답을 필터합니다.
        • 프록시서버는 또 클라이언트로부터 요청의 자원을 분산시켜줍니다. 이런 것을 Load Balancer라 하고 자원을 분산시키는 알고리즘엔 라운드 로빈, 해싱, 알고리즘 가중치 방식이 있습니다.
      •  게이트웨이 서버
        • 서로 다른 통신망, 프로토콜을 사용하는 네트워크 간의 통신을 가능하게 합니다. 
          ( HTTP 프로토콜 이외의 통신, FTP, SMT 등) 

  • [ 결과 ]
    • 브라우저(Chrome)와 웹서버의 통신 과정에 대해 상세히 아래 내용들을 이해하였습니다.
      • url이 무엇이고 브라우저가 분석할 대상이 무엇인지
      • dns서버에선 IP를 Domain Name으로 언제 변경하는지
      • Http 통신과 Https 통신의 차이점은 어느 부분에서 일어나는지
      • TCP 통신을 위해 소켓은 어디에서 생성하는지
      • Httpd가 무엇인지
      • 웹 엔진이 html, script, css 데이터는 어떻게 처리하여 렌더 하는지
      • Spring 처리과정이 무엇인지
      • 웹 서버 처리과정이 무엇인지
      • WAS 톰켓이 처리과정이 무엇인지

  • [ 성과 ]
    • 웹의 전반적인 데이터 처리 흐름을 깊게 이해하기 위해 나름의 우선순위를 가지고 정리해보았습니다.
    • 정리를 하면서 다시 한번 느낀 것은 정확히 알지 못하면 '설명할 수 없다'는 것입니다.
    • 기술서적 독서 중 가슴에 와 닿는 문구였던 '당신이 어떤 것을 초등학생에게 설명해 주지 못한다면, 그것은 진정으로 이해한 것이 아니다.' 이 문구를 항상 가슴 깊이 새기는 계기가 되었습니다.
    • 앞으로 무엇인가 새로운 지식을 학습해 실무에 적용할 때에도 '대충'이 아닌 '정확한 이해'를 바탕으로 문제를 해결해 나가야겠다고 생각이 되는 계기가 되었습니다. 

+ Recent posts