Post

웹 서버

5. 웹 서버

5.1 다채로운 웹 서버

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

웹 서버는 기능, 형태, 크기가 다양

기능은 달라도, 모든 웹 서버는 리소스에 대한 HTTP 요청을 받아서 콘텐츠를 클라이언트에게 돌려줌

5.1.1 웹 서버 구현

웹 서버는 HTTP 및 그와 관련된 TCP 처리를 구현한 것

웹 서버는 자신이 제공하는 리소스를 관리하고 웹 서버를 설정, 통제, 확장하기 위한 관리 기능을 제공

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

microsoft 웹서버, apache, nginx …

5.1.3 임베디드 웹 서버

일반 소비자용 제품에 내장될 목적으로 만들어진 작은 웹 서버(ex. 프린터나 가전제품)

5.2 간단한 펄 웹 서버

HTTP/1.1의 기능들을 지원하려면, 풍부한 리소스 지원, 가상 호스팅, 접근 제어, 로깅. 설정, 모니터링, 그 외 성능을 위한 각종 기능들이 필요

최소한의 기능을 하는 HTTP 서버 구현 가능

5.3 진짜 웹 서버가 하는 일

  1. 커넥션을 맺는다
  2. 요청을 받는다
  3. 요청을 처리
  4. 리소스에 접근
  5. 응답을 만든다
  6. 응답을 보낸다
  7. 트랜잭션 로그를 남긴다

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

5.4.1 새 커넥션 다루기

클라이언트가 웹 서버에 TCP 커넥션을 요청하면, 웹 서버는 그 커녁션을 맺고 TCP 커넥션에서 IP 주소를 추출하여 커넥션 맞은편에 어떤 클라이언트가 있는지 확인

새 커넥션에 맺어지고 받아들여지면, 서버는 새 커넥션을 커넥션 목록에 추가하고 커넥션에서 오가는 데이터를 지켜보기 위한 준비를 함

웹 서버는 어떤 커넥션이든 마음대로 거절하거나 즉시 닫을 수 있다.

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

대부분의 웹 서버는 역방향 DNS(reverse DNS)를 사용해서 클라이언트의 IP 주소를 클라이언트의 호스트 명으로 변환하도록 설정되어 있음

웹 서버는 클라이언트 호스트 명을 구체적인 접근 제어와 로깅을 위해 사용 가능

호트스명 룩업은, 꽤 시간이 많이 걸릴 수 있어 특정 콘텐츠에서만 켜놓음

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

ident 프로토콜은 서버에게 어떤 사용자 이름이 HTTP 커넥션을 초기화했는지 찾아낼 수 있게 해줌

ident는 조직 내부에서는 잘 사용할 수 있지만, 공공 인터넷에서는 여러 이유로 잘 동작하지 않음

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

보통 ident 정보가 없기 때문에 일반 로그 포맷 로그파일의 두 번째 필드는 하이픈으로 채워짐

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

요청 메시지 파싱 과정

  • 요청줄을 파싱하여 요청 메서드, 지정된 리소스의 식별자(URI), 버전 번호를 찾음
  • 메시지 헤더들을 읽음
  • 헤더의 끝을 의미하는 CRLF로 끝나는 빈 줄을 찾아냄
  • 요청 본문이 있다면, 읽어 들임(길이는 Content-Length 헤더로 정의됨)

5.5.1 메시지의 내부 표현

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

ex. 요청 메시지의 각 조각에 대한 포인터와 길이, 룩업 테이블

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

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

웹 서버들은 항상 새 요청을 주시하고 있다.

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

단일 스레드 웹 서버

한 번에 하나씩 요청을 처리

트랜잭션이 완료되면, 다음 커넥션 처리

처리 도중에 모든 다른 커넥션 무시

심각한 성능 문제를 만들어내므로 오직 로드가 적은 서버나 진단도구에서만 적당

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

여러 요청을 동시에 처리하기 위해 여러 개의 프로세스 혹은 고효율 스레드 할당

수많은 프로세스나 스레드는 너무 많은 메모리나 시스템 리소스를 소비함

그래서 많은 멀티스레드 웹 서비스가 스레드/프로세스의 최대 개수에 제한을 건다

다중 I/O 서버

모든 커넥션은 동시에 그 활동을 감시당함

커넥션의 상태가 바뀌면, 그 커넥션에 대해 작은 양의 처리가 수행

그 처리가 완료되면, 커넥션은 다음번 상태 변경을 위해 커넥션 목록으로 돌아감

어떤 커넥션에 대해 작업을 수행하는 것은 그 커넥션에 실제로 해야 할 일이 있을 때 뿐

다중 멀티스레드 웹 서버

여러 개의 스레드는 각각 열려있는 커넥션을 감시하고 각 커넥션에 대해 조금씩 작업을 수행

5.6 단계 3: 요청 처리

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

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

웹 서버는 리소스 서버(정적 콘첸츠 + 동적 콘텐츠 제공)

5.7.1 Docroot

웹 서버는 여러 종류의 리소스 매핑 지원

가장 단순한 리소스 매핑의 형태는 요청 URL를 웹 서버의 파일 시스템 안에 있는 파일 이름으로 사용하는 것ㅇ

일반적으로 웹 서버 파일 시스템의 특별한 폴더를 웹 콘텐츠를 위해 예약해 둔다 -> docroot

아파치 웹 서버의 문서 루트는 아래와 같다.

1
DocumentRoot /usr/local/httpd/files

가상 호스팅된 docroot

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

가상 호스팅 웹 서버는 URI나 Host 헤더에서 얻은 IP주소나 호스트 명을 이용해 올바른 문서 루트를 식별

아파치 웹서버에서 VirtualHost로 설정 가능

사용자 홈 디렉터리 docroots

사용자들이 한 대의 웹 서버에서 각자의 개인 웹 사이트를 만들 수 있도록 해주는 것

5.7.2 디렉터리 목록

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

대부분의 웹 서버는 클라이언트가 디렉터리 URL을 요청했을 떄 몇 가지 다른 행동을 취하도록 설정 가능

  • 에러 반환
  • 디렉터리 대신 특별한 ‘색인 파일’ 반환
  • 디렉터리를 탐색해서 그 내용을 담은 HTML 페이지 반환

아파치 웹 서버에서, DirectoryIndex 설정 지시자를 사용해서 기본 디렉터리 파일로 사용될 파일 이름의 집합 설정 가능

디렉터리 색인 파일로 사용될 모든 파일의 이름을 우선순위로 나열

1
DirectoryIndex index.html index.htm home.html

기본 색인 파일이 없고 디렉터리 색인 기능이 꺼져 있지 않다면, 많은 웹 서버는 자동으로 그 디렉터리의 파일들을 크기, 변경일 및 그 파일에 대한 링크와 함께 열거한 HTML 파일 반환

5.7.3 동적 콘텐츠 리소스 매핑

URL를 동적 리소스에 매핑 가능

동적 리소스라면, 애플리케이션 서버는 그에 대한 동적 콘텐츠 생성 프로그램이 어디에 있는지, 그리고 어떻게 그 프로그램을 실행하는지 알려줄 수 있어야 함

아파치는 URL의 경로명이 실행 가능한 프로그램이 위치한 디렉터리로 매핑되도록 설정하는 기능 제공

1
ScriptAlias /cgi-bin /usr/local/etc/httpd/cgi-programs

또한 아파치에서는 특정 확장의 파일만 실행하도록 설정 가능

1
AddHandler cgi-script .cgi

5.7.4 서버사이드 인클루드(Server-Sied Includes, SSI)

그 리소스의 컨텐츠를 클라이언트에게 보내기 전에 처리

서버는 콘텐츠에 변수 이름이나 내장된 스크립트라 될 수 있는 어떤 특별한 패턴이 있는지 검사 -> 출력 값으로 치환 -> 동적 콘텐츠 생성

5.7.5 접근 제어

접근 제어되는 리소스에 대한 요청이 도착했을 때 웹 서버는 클라이언트의 IP주소에 근거하여 접근제어 가능 혹은 리소스에 접근하기 위한 비밀번호를 물어볼 수 있다.

5.8 단계 5: 응답 만들기

응답 메시지는 응답 상태 코드, 응답 헤더, 응답 본문을 포함

5.8.1 응답 엔터티

응답 메시지는 주로 다음을 포함

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

5.8.2 MIME 타입 결정하기

mime.types

웹 서버는 MIME 타입을 나타내기 위해 파일 이름의 확장자 사용 가능

웹 서버는 각 리소스의 MIME 타입을 계산하기 위해 확장자별 MIME 타입이 담겨 있는 파일을 탐색

매직 타이핑(magic typing)

아파치 웹 서버는 각 파일의 MIME 타입을 알아내기 위해 내용을 검사해서 알려진 패턴에 대한 테이블에 해당하는 패턴이 있는지 찾아볼 수 있다.

유형 명시(Explicit typing)

특정 파일이나 디렉터리 안의 파일들이 파일 확장자나 내용에 상관없이 어떤 MIME 타입을 갖도록 웹 서버를 설정할 수 있다.

유형 협상(Type negotiation)

어떤 웹 서버는 한 리소스가 여러 종류의 문서 형식에 속하도록 설정할 수 있다.

웹 서버가 사용자와의 협상 과정을 통해 사용하기 가장 좋은 형식을 판변할 것인지의 여부도 설정할 수 있다.

5.8.3 리다이렉션

웹 서버는 종종 성공 메시지 대신 리다이렉션 응답을 반환

Location 응답 헤더는 콘텐츠의 새로운 혹은 선호하는 위치에 대한 URI를 포함

영구히 리소스가 옮겨진 경우

리소스는 새 URL이 부여되어 새로운 위치로 옮겨졌거나 이름이 바뀌었을 수 있다.

301 Moved Permaenently 코드는 이런 종류의 리다이렉트를 위해 사용됨

임시로 리소스가 옮겨진 경우

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 상태 코드는 이런 종류의 리다이렉트를 위해 사용됨

#### 디렉터리 이름 정규화

URL 요청 끝에 빗금(/)을 빠뜨렸다면, 대부분의 웹 서버는 리다이렉트함

5.9 단계 6: 응답 보내기

서버는 커넥션 상태를 추적해야 하며 지속적인 커넥션은 특별히 주위해서 다뤄야 한다.

비지속적인 커넥션이라면, 서버는 모든 메시지를 전송했을 떄 자신 쪽의 커넥션을 닫을 것이다.

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

5.10 단계 7: 로깅

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

대부분의 웹 서버는 로깅에 대한 여러 가지 설정 양식 제공

참조

  1. HTTP 완벽 가이드
This post is licensed under CC BY 4.0 by the author.