CS/Network

HTTP: 웹 서버

kkumta 2023. 3. 13. 12:11

도서 HTTP 완벽 가이드를 읽고 알게 된 지식을 정리한 글입니다.


웹 서버

  • HTTP 요청을 처리하고 응답을 제공한다.
  • 기능, 형태, 크기가 다양하다. -> 네트워크에 연결된 컴퓨터에서 동작하는 경우, 가전제품에 내장되는 경우 등
  • 표준 컴퓨터 시스템에서 동작하는 웹 서버의 경우 Apache, nginx 서버가 많이 사용된다.

 

apache

  • 하나의 클라이언트 요청을 하나의 스레드가 처리한다.
  • 요청이 많으면 시스템 자원 낭비가 심하다.

nginx

  • 모든 클라이언트 요청을 이벤트 핸들러를 통해 정해진 개수의 스레드가 비동기적으로 처리한다.
  • 문맥 교환 비용이 적고 시스템 자원 낭비가 적다.
  • 동시 접속자 수가 많아져도 추가적인 스레드 생성 비용이 들지 않는다.

 

 

참고

아파치 HTTP 서버,  Apache와 NginX 비교, 차이점


웹 서버가 하는 일

기본 순서

  1. 커넥션을 맺는다. -> 클라이언트의 접속을 받아들이거나, 받아들이지 않는다.
  2. 요청을 받는다. -> HTTP 요청 메시지를 네트워크로부터 읽어 들인다.
  3. 요청을 처리한다. -> 요청 메시지를 해석하고 행동을 취한다.
  4. 리소스에 접근한다. -> 메시지에서 지정한 리소스에 접근한다.
  5. 응답을 만든다. -> 올바른 헤더를 포함한 HTTP 응답 메시지를 생성한다.
  6. 응답을 보낸다. -> 응답을 클라이언트에게 돌려준다.
  7. 트랜잭션을 로그로 남긴다. -> 로그 파일에 트랜잭션 완료에 대한 기록을 남긴다.

 

단계 1: 클라이언트 커넥션 수락

클라이언트와 웹 서버 사이에 커넥션이 맺어져 있지 않은 상태라고 가정해보자. 그렇다면 클라이언트와 웹 서버는 아래처럼 동작할 것이다.

  1. 클라이언트는 웹 서버에 TCP 커넥션을 보낸다.
  2. 웹 서버는 클라이언트의 IP 주소나 호스트 명을 보고 커넥션을 수락할지 결정한다. 서버는 커넥션을 거절할 수 있고, 이미 연결된 커넥션일지라도 도중에 닫을 수 있다.
    • 웹 서버는 클라이언트의 IP 주소를 호스트 명으로 변환하기 위해 역방향 DNS 기술을 활용한다.

추가로, 몇몇 웹 서버의 경우 ident 프로토콜을 통해 요청하는 사용자의 이름을 얻어 로깅에 사용한다. 이 과정은 다음과 같다.

  1. 클라이언트와 웹 서버는 새 HTTP 커넥션을 맺는다.
  2. 웹 서버는 클라이언트의 ident 포트(113)를 향해 커넥션을 연다.
  3. 웹 서버는 클라이언트의 ident 포트에 사용자 이름을 묻는 요청을 보낸다.
  4. 클라이언트는 ident 응답을 반환한다.

 


단계 2: 요청 메시지 수신

요청 메시지를 파싱한다. 메시지는 활용하기 편리한 내부 표현 형태로 파싱된다.

요청줄의 각 값은 스페이스 한 개로 분리되어 있고, 요청줄과 각 메시지 헤더는 CRLF로 끝난다. 요청 본문이 있다면 Content-Length 헤더에 기록된 만큼 읽어 들인다.

 

커넥션 입출력 처리

  단일 스레드 아키텍처 멀티 프로세스/스레드 아키텍처
단일 I/O 아키텍처 한 번에 하나씩 요청을 처리하고, 한 트랜잭션이 완료된 뒤에 다음 커넥션을 처리한다.
어떤 요청을 처리하는 도중에는 모든 다른 커넥션을 무시한다.
여러 요청을 동시에 처리한다.
매우 많은 커넥션을 동시에 처리하기 위해 수많은 프로세스/스레드를 만들면 시스템 자원을 과도하게 사용하므로, 멀티스레드 웹 서비스는 프로세스/스레드의 최대 개수에 제한을 둔다.
다중 I/O 아키텍처 다중 커넥션을 지원한다.
현재 처리되고 있지 않은 커넥션은 열린 커넥션 목록에 보관되고, 그동안 다른 커넥션이 처리된다. 열린 커넥션 목록에 있는 커넥션들은 처리가 가능해질 때 처리된다. 
스레드/프로세스는 유휴 상태의 커넥션을 기다리는 데 시간을 낭비하지 않는다.
멀티스레딩과 다중화를 결합한 것이다.
여러 개의 스레드가 각 스레드마다의 열려있는 커넥션을 감시하고 처리한다.

 


단계 3: 요청 처리

요청으로부터 메서드, URI, 버전 번호, 헤더, 본문을 받아 처리한다.

 


단계 4: 리소스의 매핑과 접근

  • 웹 서버 == 리소스를 제공하는 서버
    따라서 웹 서버는 요청에 따른 리소스를 서버 내부에서 식별해야 한다.
  • 웹 서버는 요청 메시지에서 URI를 가져와서 문서 루트(docroot, 웹 콘텐츠를 위해 예약해둔 웹 서버 파일 시스템의 특별한 폴더) 뒤에 붙인다.
    예를 들어, /apple.jpeg 요청이 들어오면, 문서 루트인 /resources 뒤에 붙여 /resources/apple.jpeg 경로를 만들어 해당 경로의 파일을 반환한다.
    서버는 요청 메시지의 URI이 문서 루트를 벗어나지 않도록 해야 한다. 쉽게 말해, ../ 와 같은 URI를 허용하지 않는 것이다.
  • 가상 호스팅 웹 서버는 URI나 Host 헤더에서 얻은 IP 주소나 호스트 명을 이용해, 하나의 웹 서버 위에서 두 개의 사이트가 완전히 분리된 콘텐츠를 갖고 호스팅되도록 하는 것이다. 예를 들면 다음과 같다.
    www.abcdefg.com 요청이 들어왔을 때는 resources/abcdefg/index.html을 가져온다.
    www.zzzzzz.com 요청이 들어왔을 때는 resources/zzzzzz/index.html을 가져온다.
  • 웹 서버가 디렉터리 URI에 대한 요청을 받는다면, 에러를 반환하거나, 색인 파일을 반환하거나, 디렉터리를 탐색해서 그 내용을 담은 html 페이지를 반환한다.
    • 대부분의 웹 서버는 색인 파일인 index.html을 반환한다. 파일이 제공되는 우선순위는 DirectoryIndex 설정 지시자를 통해 설정할 수 있다.
    • 많은 웹 서버는 기본 색인 파일이 없고 디렉터리 색인 기능이 켜져 있다면, 해당 디렉터리에 있는 파일들을 열거한 HTML을 반환한다.
  • 웹 서버는 URI를 동적 리소스에 매핑할 수 있다.
    서버는 URI의 경로명이 실행 가능한 프로그램이 위치한 디렉터리로 매핑되도록 설정할 수 있다.
    아파치의 경우 ScriptAlias /appple/ /user/product/apple/이면 URI의 경로가 /appple/일 때 /user/product/apple/에서 프로그램을 찾아 실행한다.
  • 서버사이드 인클루드(SSI)
    서버는 콘텐츠에 변수 이름이나 내장된 스크립트가 될 수 있는 패턴이 있는지 검사한다. 이 패턴은 변수 값이나 스크립트의 출력 값으로 치환된다. 이렇게 하면 쉽게 동적 콘텐츠를 만들 수 있다.

 


단계 5: 응답 만들기

응답 본문을 생성해야 한다면

  • MIME 타입을 서술하는 Content-Type 헤더를 포함한다.
    • MIME 타입은 파일 이름의 확장자 사용, 파일 내용을 검사하여 알고 있는 패턴 테이블에 있는 패턴인지 찾아보기, 다른 것에 상관없이 특정 MIME 타입으로 하기 등에 의해  결정된다.
    • 한 리소스가 여러 종류의 문서 형식에 속하도록 설정할 수도 있다.
  • 응답 본문의 길이를 서술하는 Content-Length 헤더를 포함한다.

 

리다이렉션

  • 영구히 리소스가 옮겨진 경우, 301 Permanently
  • 임시로 리소스가 옮겨지거나, 이름이 변경된 경우, 303 See Other, 307 Temporary Redirect
  • 상태 정보를 포함시킨 새 URL을 생성한 경우, 303 See Other, 307 Temporary Redirect
  • 과부하된 서버가 있을 때, 303 See Other, 307 Temporary Redirect
  • 요청한 클라이언트에 대한 정보를 가지고 있는 다른 서버로 리다이렉트, 303 See Other, 307 Temporary Redirect
  • 요청 시 '/'을 빠뜨렸을 경우, '/'를 추가한 URI로 리다이렉트

 

 

단계 6: 응답 보내기

클라이언트에게 응답을 돌려준다.

 


단계 7: 로깅

트랜잭션이 완료되고, 트랜잭션이 어떻게 수행되었는지에 대한 로그를 기록한다.


 

'CS > Network' 카테고리의 다른 글

HTTP: 클라이언트 식별과 쿠키  (0) 2023.03.20
HTTP: 캐시  (0) 2023.03.13
HTTP: HTTP 메시지  (0) 2023.03.06
HTTP: URL과 리소스  (0) 2023.02.26
HTTP: HTTP 개관  (0) 2023.02.22