[HTTP] 5장: 웹 서버

서정범·2023년 7월 8일
0

HTTP

목록 보기
8/13
post-thumbnail

웹 서버

웹 서버는 월드 와이드 웹에서 사용자의 컴퓨터나 모바일 장치로 전송하는 컴퓨터 시스템이나 소프트웨어를 말합니다. 웹 서버는 HTTP(Hypertext Transfer Protocol)를 통해 클라이언트(일반적으로 웹 브라우저)로부터 요청을 받고, 이를 처리하여 결과를 다시 클라이언트에게 보내주는 역할을 합니다.

웹 서버는 웹 사이트의 모든 컴포넌트를 호스팅하는데, 이에는 HTML, CSS, JavaScript 파일, 이미지 및 비디오 파일 등이 포함될수 있습니다. 또한 웹 서버는 다양한 사이즈의 트래픽을 처리할 수 있어야 하며, 때로는 보안 인증, URL 리다이렉션, 로깅, 에러 핸들링 등의 추가 기능을 제공하기도 합니다.

웹 서버는 하드웨어와 소프트웨어두 가지 형태로 존재할 수 있습니다. 하드웨어 웹 서버는 물리적인 컴퓨터로, 웹 사이트의 파일과 애플리케이션을 저장하며, 네트워크를 통해 요청을 받아 처리합니다. 소프트웨어 웹 서버는 운영 체제 상에서 실행되는 프로그램으로, HTTP 프로토콜을 통해 웹 페이지를 전송하는 역할을 합니다. Apache, Nginx, Microsoft's Internet Information Services(IIS) 등이 대표적인 웹 서버 소프트웨어입니다.

웹 서버가 하는 일

기본적으로 웹 서버는 TCP/IP 위에서 동작하기 때문에 커넥션이 필요로 합니다. 이것을 HTTP 커넥션이라고 부릅니다.

먼저, 기본적인 커넥션은 다음과 같은 과정을 통해 이루어집니다.

  1. 특정 포트를 통해서 로컬 TCP 소켓을 만들어 줍니다.
  2. 소켓을 생성하고 커넥션을 기다리도록(listen) 설정하빈다.
  3. 클라이언트로부터 커넥션 요청이 들어오면 누구로부터의 커넥션인지 확인합니다.
  4. 커넥션을 맺고 데이어를 전송하거나 받습니다.

웹 서버는 커넥션을 맺고 나서 다음과 같은 동작을 수행합니다.

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

전체적인 기능들을 알아봤으니 좀 더 구체적인 일에 대해서 알아보자.

커넥션

웹 서버는 커넥션을 맺기 위해서 클라이언트를 식별할 필요가 있다.

클라이언트를 식별하고 나서 해당 클라이언트와 맺어져 있는 지속 커넥션이 있는지 확인하고, 커넥션이 있다면 그것을 활용합니다.

만약, 커넥션이 없다면 새로운 커넥션을 생성합니다.

클라이언트를 식별하고 저장하기 위해서 역방향 DNS(reverse DNS)를 활용하고 구체적인 접근 제어와 로깅을 위해 활용합니다. 이 과정이 시간이 오래 걸릴 수 있어서 웹 트랜잭션을 느려지게 할 수 있기에 호스트명 분석을 꺼두거나 특정 컨텐츠에서만 켜놓기도 합니다.

요청

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

  1. 요청을 파싱하여 요청 메서드, 지정한 리소스의 식별자(URI), 버전 번호를 찾습니다.
  2. 메시지 헤더들을 읽습니다.
  3. 헤더의 끝을 의미하는 CRLF로 끝나는 빈 줄을 찾아냅니다.(존재한다면)
  4. 요청 본문이 있다면, 읽어 들입니다.(길이는 Content-Length 헤더로 정의됩니다.)

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

웹 서버 아키텍처의 차이에 따라 요청을 처리하는 방식이 달라지는데, 웹 서버 입력/출력 아키텍처는 4가지가 존재합니다.

  1. 단일-스레드 I/O 아키텍처
  2. 멀티스레드 I/O 아키텍처
  3. 다중 I/O 아키텍처
  4. 다중, 멀티스레드 I/O 아키텍처

단일 스레드 웹 서버의 경우, 한 번에 하나씩 요청을 처리합니다. 트랜잭션이 완료되면, 다음 커넥션이 처리됩니다.

멀티프로세스와 멀티스레드 웹 서버의 경우, 여러 요청을 동시에 처리하기 위해 여러 개의 프로세스 혹은 고효율 스레드를 할당합니다.

다중 I/O 서버의 경우, 모든 커넥션의 활동을 동시에 감시합니다. 많은 웹 서버는 이 방식을 채택했습니다. 커넥션의 상태가 바뀌면, 그 커넥션에 대해 작은 양의 처리가 수행됩니다. 그 처리가 완료되면 커넥션은 다음번 상태 변경을 위해 열린 커넥션 목록으로 돌아갑니다.

다중 멀티스레드 웹 서버의 경우, 컴퓨터 플랫폼에 올라와 있는 CPU 여러 개의 이점을 살리기 위해 멀티스레딩과 다중화(multiplexing)를 결합합니다.

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

리소스의 매핑과 접근

웹 서버리소스 서버다. 그들은 HTML 페이지나 JPEG 이미지 같은 미리 만들어진 콘텐츠를 제공하며, 마찬가지로 서버 위에서 동작하는 리소스 생성 애플리케이션을 통해 만들어진 동적 컨텐츠도 제공합니다.

리소스 매핑의 가장 단순한 형태는 요청 URI를 웹 서버의 파일 시스템 안에 있는 파일 이름으로 사용하는 것입니다. 웹 서버에서 특정 도메인의 웹 콘텐츠가 저장되는 디렉토리를 우리는 "docroot" 또는 "document root"라고 부릅니다.

서버의 리소스를 효율적으로 사용하면서 여러 웹사이트를 동시에 호스팅할 수 있게 해주기 위해서 가상 호스팅 기능을 사용합니다.

❗가상 호스팅

가상 호스팅은 여러 도메인이 같은 웹 서버를 공유하면서도 각자 다른 웹 사이트를 운영할 수 있게 해주는 기술입니다. 가상 호스팅을 사용하면, 각 도메인마다 다른 docroot를 설정할 수 있습니다. 이렇게 하면, 도메인에 따라 요청이 들어오면 웹 서버는 해당 도메인에 설정된 docroot에서 콘텐츠를 찾게 됩니다.

이를 통해, 각 웹사이트는 독립적인 docroot를 가지므로, 서로의 데이터에 영향을 주지 않습니다. 이는 웹 호스팅 비용을 절약하는 데 도움이 되며, 여러 웹사이트를 동시에 운영하는 데 필요한 유연성을 제공합니다.

웹 서버는, 경로가 파일이 아닌 디렉토리를 가리키는, 디렉토리 URL에 대한 요청을 받을 수 있습니다. 이때 취할 수 있는 몇가지 행동을 설정할 수 있습니다.

  1. 에러를 반환합니다.
  2. 디렉토리 대신 특별한 '색인 파일'을 반환합니다.
  3. 디렉토리를 탐색해서 그 내용을 담은 HTML 페이지를 반환합니다.

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

아파치에서는 이것을 위해서 다음과 같은 기능을 제공합니다.

  1. 특정 경로 매칭
  2. 특정 확장자 파일만 실행

만약 어떤 리소스가 서버사이드 인클루드를 포함하고 있는 것으로 설정되어 있다면, 서버는 그 리소스의 콘텐를 클라이언트에게 보내기 전에 직접 처리합니다.

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

응답

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

만약, 트랜잭션이 응답 본문을 생성한다면, 그 내용을 응답 메시지와 함계 돌려보냅니다. 만약 본문이 있다면, 응답 메시지는 주로 다음을 포함합니다.

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

웹 서버는 종종 성공 메세지 대신 리다이렉션 응답을 반환하기도 합니다. 리다이렉트의 경우 다음과 같은 상황에서 유용합니다.

  1. 영구히 리소스가 옮겨진 경우
  2. 임시로 리소스가 옮겨진 경우
  3. URL 증강: 문맥 정보를 포함시키기 위해 재 작성된 URL로 리다이렉트
  4. 부하 균형
  5. 친밀한 다른 서버가 있는 경우: 클라이언트에 대한 정보를 가지고 있는 다른 서버로 리다이렉트
  6. 디렉토리 이름 정규화

Reference

profile
개발정리블로그

0개의 댓글