Skip to main content

5. 웹 서버

아래에서는 다음의 내용을 다룹니다.

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

5.1 다채로운 웹 서버#

웹 서버는 HTTP 요청을 처리하고 응답을 제공합니다.

웹 서버 구현#

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

다목적 소프트웨어 웹 서버#

  • 네트워크에 연결된 표준 컴퓨터 시스템에서 동작합니다.
  • 웹 서버 소프트웨어는 거의 모든 컴퓨터와 운영체제에서 동작합니다.

임베디드 웹 서버#

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

5.2 간단한 펄 웹 서버#

  • HTTP/1.1의 기능들을 지원하려면, 풍부한 리소스 자원, 가상 호스팅, 접근 제어, 로깅, 설정, 모니터링, 그 외 성능을 위한 각종 기능들이 필요합니다.
  • 최소한의 기능으로 가능하는 HTTP 서버라면 30줄 이하의 펄 코드로도 만들 수 있습니다. (코드 생략)

5.3 진짜 웹 서버가 하는 일#

일반적으로 웹 서버의 순서는 다음과 같습니다.

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

5.4 단계 1: 클라이언트 커넥션 추가#

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

새 커넥션 다루기#

  • 클라이언트가 웹 서버에 TCP 커넥션을 요청하면 웹 서버는 그 커넥션을 맺고 TCP 커넥션에서 IP 주소를 추출하여 커넥션 맞은편에 어떤 클라이언트가 있는지 확인합니다.
  • 커넥션은 언제든 닫을 수 있습니다.

클라이언트 호스트 명 식별#

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

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

  • 몇몇 웹 서버는 IETF ident 프로토콜을 지원합니다.
  • ident 프로토콜은 서버에게 어떤 사용자 이름이 HTTP 커넥션을 초기화했는지 찾아낼 수 있게 해줍니다.
  • ident는 조직 내부에서는 잘 사용할 수 있지만 공공 인터넷은 다음의 이슈로 인해서 자주 사용하지 않습니다.
    • 많은 클라이언트 PC는 identd 신원확인 프로토콜 데몬 소프트웨어를 실행하지 않습니다.
    • ident 프로토콜은 HTTP 트랜잭션을 유의미하게 지연시킵니다.
    • 방화벽이 ident 트래픽이 들어오는 것을 막는 경우가 많습니다.
    • ident 프로토콜은 안전하지 않고 조작하기 쉽습니다.
    • ident 프로토콜은 가상 IP 주소를 잘 지원하지 않습니다.
    • 클라이언트 사용자 이름의 노출로 인한 프라이버시 침해의 우려가 있습니다.

5.5 단계 2: 요청 메시지 수신#

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

요청 메시지를 파싱할 때, 웹 서버는 다음과 같은 일을 합니다.

  • 요청줄을 파싱하여 요청 메서드, 지정된 리소스의 식별자, 버전 번호르 찾습니다.
  • 메시지 헤더를 읽습니다.
  • 헤더의 끝을 읨하는 CRLF로 끝내는 빈 줄을 찾습니다.
  • 요청 본문이 있다면 읽습니다.

요청 메시지를 파싱할 때, 웹 서버는 입력 데이터를 네트워크로부터 불규칙적으로 받고, 네트워크 커넥션은 언제든 무효화 될 수 있습니다. 따라서 이런 경우 메시지 일부분을 메모리에 임시로 저장할 필요가 있습니다.

메시지의 내부 표현#

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

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

  • 고성능 웹 서버는 수천 개의 커넥션을 동시에 열 수 있도록 지원합니다.

단일 스레드 웹 서버#

  • 한번에 하나씩 요청을 처리합니다.

멀티프로세스와 멀티스레드 웹 서버#

  • 여러 요청을 동시에 처리하기 위해 여러 개의 프로세스 혹은 고효율 스레드를 할당합니다.
  • 너무 많은 메모리나 시스템 리소스 소비를 하는 경우, 최대 개수에 제한을 겁니다.

다중 I/O 서버#

  • 대량의 커넥션을 지원하기 위해 많은 웹 서버는 다중 아키텍처를 채택합니다.
  • 모든 커넥션은 동시에 그 활동을 감시당합니다.
  • 커넥션에 대해 작업을 수행하는 것은 커넥션에 실제로 해야할 일이 있을때만 이므로 리소스를 낭비하지 않습니다.

다중 멀티스레드 웹 서버#

  • 일부의 경우는 멀티스레딩과 다중화를 결합합니다.
  • 여러 개의 스레드는 각각 열려있는 커넥션을 감시하고 각 커넥션에 대해 조금씩 작업을 수행합니다.

5.6 단계 3: 요청 처리#

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


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

웹 서버는 리소스 서버입니다. 즉, 만들어진 컨텐츠를 제공하거나 서버위에서 동작하는 동적 콘텐츠를 제공합니다.

Docroot#

  • 웹 서버는 여러 종류의 리소스 매핑을 지원합니다.
  • 요청 URI를 웹 서버의 파일 시스템 안에 있는 파일 이름으로 사용하는 것입니다.
  • 웹 서버 파일 시스템의 특별한 폴더를 웹 콘텐츠를 위해 예약해두며 이를 문서 루트, docroot로 불립니다.

가상 호스팅된 docroot#

  • 가상 호스팅 웹 서버는 각 사이트에 그들만의 분리된 문서 루트를 주는 방법으로 한 웹 서버에서 여러 개의 웹 사이트를 호스팅합니다.

사용자 홈 디렉터리 doroots#

  • 사용자들이 한 대의 웹 서버에서 각자의 개인 웹 사이트를 만들 수 있도록 해줍니다.

디렉터리 목록#

  • 웹 서버는 경로가 파일이 아닌 디렉터리를 가리키는 디렉터리 URL에 대한 요청을 받을 수 있습니다.

동적 콘텐츠 리소스 매핑#

  • 웹 서버는 URI를 동적 리소스에 매핑할 수도 있습니다.
  • 요청에 맞게 콘텐츠를 생성하는 프로그램에 URI를 매핑하는 것입니다.

서버사이드 인클루드(Server-Side Includes, SSI)#

  • 많은 웹 서버가 서버사이드 인클루드도 지원합니다.
  • 어떤 리소스가 서버사이드 인클루드를 포함하고 있는 것으로 설정되어 있다면, 서버는 그 리소스의 콘텐츠를 클라이언트에게 보내기 전에 처리합니다.

접근 제어#

  • 웹 서버는 또한 각각의 리소스에 접근 제어를 할당할 수 있습니다.

5.8 단계 5: 응답 만들기#

한번 서버가 리소스를 식별하면, 서버는 요청 메서드로 서술되는 동작을 수행한 뒤 응답 메시지를 반환합니다.

응답 에티티#

일반적으로 다음을 포함합니다.

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

MIME 타입 결정하기#

  • mime.types : 파일 이름의 확장자를 사용합니다.
  • 매직 타이핑(Magic typing) : 아파치 웹 서버에서 파일 내용을 검사해서 알려진 패턴 테이블에 해당하는 패턴을 찾습니다.
  • 유형 명시(Explicit typing) : 특정 파일이나 디렉터리 안의 파일들이 파일 확장자나 내용에 상관없이 어떤 MIME 타입을 갖도록 웹 서버를 설정합니다.
  • 유형 협상(Type negotiation) : 어떤 웹 서버는 한 리소스가 여러 종류의 문서 형식에 속하도록 설정할 수 있습니다.

리다이렉션#

웹 서버는 종종 성공 메시지 대신 리다이렉션 응답을 반환합니다. 일반적으로 3XX 상태 코드를 지칭됩니다. 리다이렉트는 다음의 경우에 유용합니다.

  • 영구히 리소스가 옮겨진 경우
  • 임시로 리소스가 옮겨진 경우
  • URL 증강
  • 부하 균형
  • 친밀한 다른 서버가 있을 때
  • 디렉터리 이름 정규화

5.9 단계 6: 응답 보내기#

웹 서버는 받을 때와 마찬가지로 커넥션 너머로 데이터를 보낼 때도 비슷한 이슈에 직면합니다. 서버는 여러 클라이언트에 대한 많은 커넥션을 가질 수 있습니다.

서버는 커넥션 상태를 추적해야 하며 지속적인 커넥션은 특별히 주의해서 다룰 필요가 있습니다.


5.10 단계 7: 로깅#

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

Last updated on