ABOUT ME

-

오늘
-
어제
-
-
  • Network - 웹 서버
    Network 2020. 6. 30. 19:43

    이번 장에서 살펴볼 주제

    • 여러 종류의 소프트웨어 및 하드웨어 웹 서버에 대해 조사한다.
    • HTTP 통신을 진단해주는 간단한 웹 서버를 펄로 작성해본다.
    • 어떻게 웹 서버가 HTTP 트랜잭션을 처리하는지 단계별로 설명한다.

     

    다채로운 웹 서버

    웹 서버는 HTTP 요청을 처리하고 응답을 제공합니다. 즉, 리소스에 대한 HTTP 요청을 받아서 컨텐츠를 클라이언트에게 돌려줍니다.

    웹 서버 구현

    웹 서버는 HTTP 및 그와 관련된 TCP 처리를 구현한 것입니다. 자신이 제공하는 리소스를 관리하고 웹 서버를 설정, 통제, 확장하기 위한 관리 기능을 제공합니다.
    웹 서버는 HTTP 프로토콜을 구현하고, 웹 리소스를 관리하고, 웹 서버 관리 기능을 제공합니다. 그리고 TCP 커넥션 관리에 대한 책임을 운영체제와 나눠 갖습니다.

    다목적 소프트웨어 웹 서버

    네트워크에 연결된 표준 컴퓨터 시스템에서 동작합니다. 아파치, W3C의 직소 같은 오픈 소스 소프트웨어를 사용할 수도 있고, 마이크로소프트나 아이플래닛의 웹 서버 같은 상용 소프트웨어를 이용할 수도 있습니다. 대표적으로 마이크로소프트, 아파치, ngnix가 있습니다.

    임베디드 웹 서버

    일반 소비자용 제품에 내장될 목적으로 만들어진 작은 웹 서버입니다.

    간단한 펄 웹 서버

    완전한 기능을 갖춘 HTTP 서버를 만들고자 한다면 많은 일들이 필요하지만, 최소한의 기능을 하는 HTTP 서버라면 30줄 이하의 펄 코드로 만들 수 있습니다.

    진짜 웹 서버가 하는 일

    1. 커넥션을 맺습니다.
    2. 요청을 받습니다.
    3. 요청을 처리합니다.
    4. 리소스에 접근합니다.
    5. 응답을 만듭니다.
    6. 응답을 보냅니다.
    7. 트랜잭션을 로그로 남깁니다.

     

    클라이언트 커넥션 수락

    클라이언트가 이미 서버에 대해 열려있는 지속적 커넥션을 갖고 있다면, 클라이언트는 요청을 보내기 위해 그 커넥션을 사용할 수 있습니다. 그렇지 않다면 새 커넥션을 열 필요가 있습니다.

    새 커넥션 다루기

    클라이언트가 웹 서버에 TCP 커넥션을 요청하면, 웹 서버는 커넥션을 맺고 TCP 커넥션에서 IP 주소를 추출하여 커넥션 맞은편에 어떤 클라이언트가 있는지 확인합니다. 서버는 커넥션이 맺어지면 커넥션 목록에 추가하고 데이터가 오는 것을 기다립니다. 그리고 웹 서버는 어떤 커넥션이든 거절하거나 즉시 닫을 수 있습니다.

    클라이언트 호스트 명 식별

    대부분의 웹 서버는 역방향 DNS를 사용해서 클라이언트의 IP 주소를 클라이언트의 호스트 명으로 변환하도록 설정되어 있습니다. 웹 서버는 클라이언트 호스트명을 구체적인 접근 제어로깅을 위해 사용할 수 있습니다. 호스트명 룩업은 많은 시간이 걸릴 수 있어 웹 트랜잭션을 느려지게 할 수 있습니다.

    ident 를 통해 클라이언트 사용자 알아내기

    ident 프로토콜은 서버에게 어떤 사용자 이름이 HTTP 커넥션을 초기화했는지 찾도록 해줍니다. 이 정보는 로깅에서 유용하기 때문에, 널리 쓰이는 일반 로그 포맷의 두 번째 필드는 각 HTTP 요청의 ident 사용자 이름을 담고있습니다. ident 는 조직 내부에서는 잘 사용할 수 있지만,
    공공 인터넷에서는 아래의 이유로 잘 동작하지 않습니다.

    • 많은 클라이언트 PC 는 identd 신원확인 프로토콜 데몬 소프트웨어를 실행하지 않습니다.
    • HTTP 트랜잭션을 유의미하게 지연시킵니다.
    • 방화벽이 ident 트래픽을 막는 경우가 많습니다.
    • ident 프로토콜은 아전하지 않고 조작하기 쉽습니다.
    • 가상 IP 주소를 잘 지원하지 않습니다.
    • 프라이버시 침해에 우려가 있습니다.

     

    요청 메세지 수신

    커넥션에 데이터가 도착하면, 웹 서버는 네트워크 커넥션에서 데이터를 읽어 들이고 파싱하여 요청 메시지를 구성합니다.
    요청 메시지를 파싱할 떄 아래와 같은 일을 합니다.

    • 요청줄을 파싱하여 요청 메서드, 지정된 리소스의 식별자(URI), 버전 번호를 찾습니다.
    • 메세지 헤더들을 읽습니다.
    • 헤더의 끝을 의미하는 CRLF로 끝나는 빈 줄을 찾습니다.
    • 요청 본문이 있다면, 읽어들입니다.

    메시지의 내부 표현

    몇몇 웹 서버는 요청 메시지를 쉽게 다룰 수 있도록 내부의 자료 구조에 저장합니다.

    커넥션 입력/출력 처리 아키텍쳐

    웹 서버 아키텍처의 차이에 따라 요청을 처리하는 방식도 달라집니다.

    • 단일 스레드 웹서버: 한 번에 하나씩 요청을 처리합니다. 트랜잭션이 완료되면, 다음 커넥션이 처리됩니다. 처리 도중에 다른 커넥션은 무시됩니다. 성능 문제가 있기 때문에 로드가 적은 서버나 진단 서버 같은 간단한 작업에 적합합니다.

    • 멀티 프로세스와 멀티 스레드 웹 서버: 여러 요청을 동시에 처리하기 위해 여러 개의 프로세스 혹은 고효율 스레드를 할당합니다. 수많은 프로세스나 스레드는 너무 많은 메모리나 시스템 리소스를 소비하기 때문에 최대 갯수에 제한을 거는 것이 좋습니다.

    • 다중 I/O 서버: 대량의 커넥션을 지원하기 위해, 많은 웹 서버는 다중 아키텍처를 채택했습니다. 모든 커넥션은 동시에 활동을 감시당합니다. 커넥션의 상태가 바뀌면 해당 커넥션에 대해 작은 양의 처리가 수행됩니다. 작업 수행은 실제로 해야 할 일이 있을 때만 수행됩니다. 리소스를 낭비하지 않습니다.

    • 다중 멀티스레드 웹 서버: 몇몇 시스템은 자신의 컴퓨터 플랫폼에 올라와 있는 CPU 여러 개의 이점을 살리기 위해 멀티스레딩과 다중화를 결합합니다. 열려있는 커넥션을 감시하고 커넥션에 대해 조금씩 작업을 진행합니다.

     

    요청 처리

    요청을 받으면 요청으로부터 메소드, 리소스, 헤더, 본문을 얻어내어 처리합니다.

    리소스의 매핑과 접근

    웹 서버가 클라이언트에 콘텐츠를 전달하려면, 그전에 요청 메시지의 URI에 대응하는 알맞은 콘텐츠나 콘텐츠 생성기를 웹서버에서 찾아서 컨텐츠의 원천을 식별해야합니다.

    Docroot

    리소스 매칭의 가장 단순한 형태는 요청 URI를 웹 서버의 파일 시스템 안에 있는 파일 이름으로 사용하는 것입니다. 일반적으로 웹 서버 파일 시스템의 특별한 폴더를 웹 콘텐츠를 위해 예약해둡니다. 이 폴더를 루트 또는 Docroot라고 합니다.

    • 가상 호스팅된 docroot : 각 사이트에 그들만의 분리된 문서 루트를 만들어 주는 방법입니다. URI나 Host 헤더에서 얻은 IP 주소나 호스트 명을 이용해 올바른 문서 루트를 식별합니다.

    • 사용자 홈 디텍터리 docroots : 사용자들이 한 대의 웹 서버에서 각자의 개인 웹 사이트를 만들 수 있도록 하는 것입니다. 보통 /, ~ 다음에 사용자 이름이 오는 것으로 시작하는 URI 는 사용자의 개인 문서 루트를 가리킵니다.

     

    디렉터리 목록

    웹 서버는 경로가 파일이 아닌 디렉터리를 가리키는, 디렉터리 URL 요청을 받을 수도 있습니다. 대부분의 웹 서버는 디렉터리 URL을 요청했을 때 아래과 같이 몇 가지 다른 행동을 취하도록 설정 할 수 있습니다.

    • 에러를 반환합니다.
    • 디렉터리 대신 특별한 색인 파일을 반환합니다.
    • 디렉터리 내용을 담은 HTML 페이지를 반환합니다.

    동적 콘텐츠 리소스 맵핑

    웹 서버는 URI를 동적 리소스에 매핑할 수도 있습니다. 즉, 요청에 맞게 컨텐츠를 생성하는 프로그램에 URI를 매핑하는 것입니다. 애플리케이션 서버라고 불리는 것들은 웹 서버를 복잡한 백엔드 애플리케이션과 연결하는 일을 합니다. 애플리케이션 서버는 그에 대한 동적 콘텐츠 생성 프로그램이 어디에 있는지, 그리고 어떻게 프로그램을 실행하는지 알려줄 수 있어야 합니다.

    서버사이드 인클루드

    서버는 콘텐츠에 변수 이름이나 내장된 스크립트가 될 수 있는 어떤 특별한 패턴이 있는지 검사를 받습니다. 특별한 패턴을 변수 값이나 실행 가능한 스크립트의 출력 값으로 치환됩니다. 이것은 동적 컨텐츠를 만드는 쉬운 방법입니다.

    접근 제어

    웹 서버는 각각의 리소스에 접근 제어를 할당 할 수 있습니다. IP 혹은 비밀번호를 물어볼 수 있습니다.

    응답 만들기

    서버가 리소스를 식별하면, 서버는 요청 메서드로 서술되는 동작을 수행한 뒤 응답 메세지를 반환합니다. 응답 메세지는 상태 코드, 헤더, 본문을 포함합니다.

    응답 엔터티

    만약 트랜잭션이 응답 본문을 생성한다면, 그 내용을 메시지와 함께 돌려보냅니다. 메시지는 아래의 내용을 포함합니다.

    • MIME 타입을 서술하는 Content-Type 헤더
    • 길이를 서술하는 Content-Length 헤더
    • 실제 응답 본문의

     

    MIME 타입 결정하기

    웹 서버에게는 응답 본문의 MIME 타입을 결정해야 하는 책임이 있습니다. 아래는 MIME 타입과 리소스를 연결하는 여러가지 방법입니다.

    • mime.types : MIME 타입을 나타내기 위해 파일 이름의 확장자를 사용 할 수 있습니다. 리소스의 MIME 타입을 계산하기 위해 확장자별 MIME 타입이 담겨 있는 파일을 탐색합니다.
    • 매직 타이핑 : 파일의 내용을 검사해서 알려진 패턴에 대한 테이블에 해당하는 패턴이 있는지 찾아 볼 수 있습니다.
    • 유형 명시 : 특정 파일이나 디렉터리 안의 파일들이 파일 확장자나 내용에 상관없이 어떤 MIME 타입을 갖도록 설정할 수 있습니다.
    • 유형 협상 : 리소스가 여러 종류의 문서 형식에 속하도록 설정할 수 있습니다.

     

    리다이렉션

    웹 서버는 종종 성공 메세지 대신 리다이렉션 응답을 반환합니다. 요청을 수행하기 위해 브라우저가 다른 곳으로 가도록 리다이렉트 할 수 있습니다. 아래의 경우에 유용하게 사용됩니다.

    • 리소스가 옮겨진 경우 : 리소스 이름이 바뀌었다고 클라이언트에게 새로운 북마크를 갱신 할 수 있다고 알려줍니다. 301 moved Permanently 상태 코드가 사용됩니다.
    • 임시로 리소스가 옮겨진 경우 : 나중에는 원래 URL로 찾아오고 북마크도 갱신하지 않기를 원합니다. 303 see other, 307 temporary redirect 상태 코드가 사용됩니다.
    • URL 증강 : 문맥 정보를 포함시키기 위해 재 작성된 URL로 리다이렉트합니다. 303 see other, 307 temporary redirect 상태 코드가 사용됩니다.
    • 부하 균형 : 부하가 덜 걸린 서버로 리다이렉트 할 수 있습니다. 303 see other, 307 temporary redirect 상태 코드가 사용됩니다.
    • 친밀한 다른 서버가 있을 때 : 어떤 사용자에 대한 정보를 가질 수 있습니다. 클라이언트에 대한 정보를 갖고 있는 다른 서버로 리다이렉트 할 수 있습니다. 303 see other와 307 temporary redirect 상태 코드가 사용됩니다.
    • 디렉터리 이름 정규화 : / 를 빠뜨렸다면, 웹 서버는 정상적으로 동작할 수 있도록 자동으로 추가한 상태로 리다이렉트 합니다.

     

    응답 보내기

    서버는 커넥션 상태를 추적해야 하며 지속적인 커넥션은 특별히 주의해서 다룰 필요가 있습니다. 지속적인 커넥션이라면, 서버가 Content-Length 헤더를 바르게 계산하기 위해서 특별한 주의를 필요로 하는 경우나, 클라이언트 응답이 언제 끝나는지 알 수 없는 경우에 커넥션은 열린 상태를 유지합니다.

    로깅

    트랜잭션이 완료되었을 때 웹 서버는 트랜잭션이 어떻게 수행되었는지에 대한 로그를 로그 파일에 기록합니다.


    'Network' 카테고리의 다른 글

    Network - 캐시  (0) 2020.06.30
    Network - 프락시  (0) 2020.06.30
    Network - 커넥션 관리  (0) 2020.06.30
    Network - HTTP 메시지  (0) 2020.06.30
    Network - URL과 리소스  (0) 2020.06.30

    댓글