웹 서버

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

 

1. 공통적으로 웹 서버가 하는 일

  • 커넥션 맺기
  • 요청 받기
  • 요청 처리
  • 리소스 접근
  • 응답 만들기
  • 응답 보내기
  • 트랜잭션을 로그로 남기기

1.1 커넥션 맺기

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

그렇지 않다면, 클라이언트는 서버에 대한 새 커넥션을 열어야 합니다.

1.1.1 새 커넥션 다루기

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

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

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

그래서 어떤 웹 서버들은 클라이언트의 IP 주소나 호스트 명이 인가되지 않았거나 악의적이라고 알려진 것인 경우 커넥션을 닫습니다.

 

1.2 요청 받기

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

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

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

요청 메시지를 파싱할 때, 웹 서버는 입력 데이터를 네트워크로부터 불규칙적으로 받습니다.

네트워크 커넥션은 언제라도 무효화될 수 있기 때문에, 웹 서버는 파싱해서 이해하는 것이 가능한 수준의 분량을 확보할 때까지 데이터를 네트워크로부터 읽어서 메시지 일부분을 메모리에 임시로 저장해 둘 필요가 있습니다.

1.2.1 메시지의 내부 표현

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

예를 들어, 헤더는 속도가 빠른 룩업 테이블에 저장되어 각 필드에 신속하게 접근할 수 있습니다.

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

커넥션 입출력 처리 아키텍처는 다음과 같이 있습니다.

 

a) 단일-스레드 I/O 아키텍처

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

즉, 현재 커넥션의 트랜잭션이 완료되어야 다음 커넥션이 처리됩니다.

이 아키텍처는 구현이 간단하지만 심각한 성능 문제를 만듭니다.

 

b) 멀티스레드 I/O 아키텍처

멀티 스레드로 여러 요청을 한번에 처리합니다.

즉, 매 커넥션마다 스레드 하나를 할당하여, 여러 커넥션을 동시에 처리합니다.

이 아키텍처는 많은 수의 커넥션을 동시에 처리하게 되면, 너무 많은 메모리나 시스템 리소스를 소비합니다.

그렇기에 스레드의 최대 개수에 제한을 둡니다.

 

c) 다중 I/O 아키텍처

다중 아키텍처에서는 모든 커넥션은 동시에 그 활동을 감시당합니다.

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

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

이로써, 스레드는 유휴 상태의 커넥션에 매여 기다리느라 리소스를 낭비하지 않습니다.

 

※ 커넥션의 효율이 높아진다고 보시면 될 것 같습니다.

 

d) 다중, 멀티스레드 I/O 아키텍처

멀티스레딩과 다중화를 결합한 것입니다.

 

1.3 요청 처리

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

 

1.4 리소스의 매핑과 접근

웹 서버는 리소스 서버입니다.

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

 

웹 서버는 여러 종류의 리소스 매핑을 지원합니다.

  • Docroot : 가장 단순한 형태로 요청 URI를 웹 서버의 파일 시스템 안에 있는 파일 이름으로 사용하는 것입니다.
  • 디렉토리 목록 : 파일 이름이 아닌 디렉토리 이름을 사용함으로써 디렉토리 안에 있는 특별한 색인 파일을 반환합니다.
  • 동적 콘텐츠 리소스 매핑 : 콘텐츠를 생성하는 프로그램에 URI를 매핑하는 것입니다.
  • 서버사이드 인클루드(SSI) : 리소스의 콘텐츠를 클라이언트에게 보내기 전에 처리합니다.

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

 

1.5 응답 만들기

서버는 요청 메서드로 서술되는 동작을 수행한 뒤 응답 메시지를 반환합니다.

응답 메시지는 응답 상태 코드, 응답 헤더, 그리고 응답 본문(있다면)을 포함합니다.

 

1.6 응답 보내기

만들어진 응답 메시지를 커넥션 너머로 데이터를 보냅니다.

 

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

리다이렉트는 다음의 경우에 유용합니다.

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

1.7 로깅

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

 

마치며..

 이 글은 웹 서버에 대해 간략히 적은 글입니다.

 

저는 이번 공부에서

  • 웹 서버가 하는 일이 무엇이 있는지,
  • 어떤 순서로 하는지,
  • 각 순서에 어떤 일을 하는지,
  • 커넥션 입출력 처리 아키텍처에 무엇이 있는지

를 알아 갔습니다.

 

이번엔 커넥션 입출력 처리 아키텍처를 제외하고 가볍게 읽었습니다.

'채워가는 지식 > 네트워크' 카테고리의 다른 글

프락시  (0) 2024.02.15
STOMP 웹소켓 프로그래밍  (0) 2024.02.15
커넥션  (0) 2023.12.20
HTTP 메시지  (0) 2023.12.18
URL  (1) 2023.12.18

+ Recent posts