HTTP 완벽 가이드 5주차 5장

박정훈·2022년 8월 20일
1

HTTP 완벽 가이드

목록 보기
5/8
post-thumbnail

📚독서 스터디

독서 스터디 벌써 5주차네요. 4주차 내용이 많아 차근차근 다시 읽어가면서 포스팅을 했더니 너무 늦게 올라가는 바람에 금세 5주차 글이 돌아왔네요.
각설하고, 이번 5주차도 어김없이 읽은 내용을 정리하고 문제를 만들어 가야합니다!

이번 5장부터는 2부가 시작됩니다. 2부의 여섯 개 장은 웹 시스템 아키텍처를 구성하는 HTTP 서버, 프락시, 캐시, 게이트웨이, 로봇 애플리케이션에 대해 다룬다고 합니다.

📌웹 서버가 하는 일

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

📌커넥션 수락

⚡커넥션 다루기

클라이언트가 웹 서버에 TCP 커넥션을 요청하면, 웹 서버는 그 커넥션을 맺고 TCP 커넥션에서 IP 주소를 추출하여 커넥션 맞은편에 어떤 클라이언트가 있는지 확인한다. 일단 새 커넥션이 맺어지고 받아들여지면, 서버는 새 커넥션을 커넥션 목록에 추가하고 커넥션에서 오가는 데이터를 지켜보기 위한 준비를 한다.

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

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

📌요청 메시지 수신

커넥션에 데이터가 도착하면, 웹 서버는 네트워크 커넥션에서 그 데이터를 읽어 들이고 파싱하여 요청 메시지를 구성한다. 요청 메시지를 파싱할 때, 웹 서버는 다음과 같은 일을 한다.

  • 요청줄을 파싱하여 요청 메서드, 지정된 리소스의 식별자(URI), 버전 번호를 찾는다. 각 값은 스페이스 한 개로 분리되어 있으며, 요청줄은 캐리지 리턴 줄바꿈(CRLF) 문자열로 끝난다.
  • 메시지 헤더들을 읽는다. 각 메시지의 헤더는 CRLF로 끝난다.
  • 헤더의 끝을 의미하는 CRLF로 끝나는 빈 줄을 찾아낸다.(존재한다면)
  • 요청 본문이 있다면, 읽어 들인다.(길이는 Content-Length 헤더로 정의된다).

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

어떤 커넥션들로부터는 요청이 느리게 혹은 드물게 흘러 들어오고, 또 어떤 것들은 나중에 일어날 활동을 위해 조용히 대기하고 있는데 비해, 일부 커넥션들은 웹 서버로 급속히 요청을 보내고 있을 것이다. 웹 서버들은 언제라도 도착할 수 있기 때문에 항상 새 요청을 주시하고 있다.

😢단일 스레드 웹 서버

단일 스레드 웹 서버는 한 번에 하나씩 요청을 처리한다. 구현하기 간단하지만 처리 도중에 모든 다른 커넥션은 무시된다. 오직 로드가 적은 서버나 type-o-serve와 같은 진단도구에서만 적당하다.

🤸‍♂️멀티프로세스와 멀티스레드 웹 서버

여러 요청을 동시에 처리하기 위해 여러개의 프로세스 혹은 고효율 스레드를 할당한다. 그렇지만 많은 프로세스나 스레드는 너무 많은 메모리나 소비하기에 많은 멀티스레드 웹 서비스가 최대 개수에 제한을 건다.

😊다중 I/O 서버

대량의 커넥션을 지원하기 위해, 많은 웹 서버는 다중 아키텍쳐를 채택했다. 모든 커넥션은 동시에 그 활동을 감시당한다. 커넥션에 대해 작은 양의 처리가 수행된다. 어떤 커넥션에 대해 작업을 수행하는 것은 그 커넥션에 실제로 해야 할 일이 있을 때뿐이다. 스레드와 프로세스는 유휴 상태의 커넥션에 매여 기다리느라 리소스를 낭비하지 않는다.

😮다중 멀티스레드 웹 서버

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

📌요청 처리

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

📌리소스의 매핑과 접근

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

⚡Docroot

리소스 매핑의 가장 단순한 형태는 요청 URI를 웹 서버의 파일 시스템 안에 있는 파일 이름으로 사용하는 것이다. 웹 서버는 요청 메시지에서 URI를 가져와서 문서 루트 뒤에 붙인다.

요청: /spEcials/saw-blade.gif
웹 서버의 문서 루트: /usr/local/httpd/files
웹 서버 반환: /usr/local/httpd/files/specials/saw-blade.gif

가상 호스팅된 docroot

각 사이트에 그들만의 분리된 문서 루트를 주는 방법으로 한 웹 서버에서 여러 개의 웹 사이트를 호스팅 한다. 가상 호스팅 웹 서버는 URI나 Host 헤더에서 얻은 IP 주소나 호스트 명을 이용해 올바른 문서 루트를 식별한다.

⚡디렉터리 목록

웹 서버는 디렉터리 URL에 대한 요청을 받을 수 있다. 다음은 클라이언트가 디렉터리 URL을 요청했을 때 취할 수 있는 동작이다.

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

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

⚡동적 콘텐츠 리소스 매핑

요청에 맞게 콘텐츠를 생성하는 프로그램에 URI를 매핑하는 것이다. 대부분의 웹 서버는 동적 리소스를 식별하고 매핑할 수 있다.

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

어떤 리소스가 서버사이드 인클루드를 포함하고 있는 것으로 설정되어 있다면, 서버는 그 리소스의 콘텐츠를 클라이언트에게 보내기 전에 처리한다. 서버는 콘텐츠에 변수 이름이나 내장된 스크립트가 될 수 있는 어떤 특별한 패턴이 있는지 검사를 받는다. 특별한 패턴은 변수 값이나 실행 가능한 스크립트의 출력 값으로 치환된다.

📌응답 만들기

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

⚡응답 엔터티

만약 트랜잭션이 응답 본문을 생성한다면, 그 내용을 응답 메시지와 함께 돌려보낸다. 그 내용으로는 다음과 같다.

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

⚡MIME 타입 결정하기

웹 서버에게는 응답 본문의 MIME 타입을 결정해야 하는 책임이 있다.

🧐mime.types

파일 이름의 확장자를 사용한다.

🤥매직 타이핑

파일의 내용을 검사해서 알려진 패턴에 대한 테이블에 해당하는 패턴이 있는지 찾아본다. 특히 표준 확장자 없이 이름 지어진 경우에는 특히 편리하다.

🤔유형 명시

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

✨유형 협상

한 리소스가 여러 종류의 문서 형식에 속하도록 설정할 수 있다. 이 때 웹 서버가 사용자와의 협상 과정을 통해 사용하기 가장 좋은 형식을 판별한 것인지의 여부도 설정할 수 있다.

⚡리다이렉션

웹 서버는 종종 성공 메시지 대신 리다이렉션 응답을 반환한다. 이는 3XX 상태 코드로 지칭된다.

  • 영구히 리소스가 옮겨진 경우 (301 상태 코드)
  • 임시로 리소스가 옮겨진 경우 (303 or 307 상태 코드)
  • URL 증강. 서버는 상태 정보를 내포한 새 URL을 생성, 사용자를 이 새 URL로 리다이렉트한다. 클라이언트는 리다이렉트를 따라가서, 이번엔 상태정보가 추가된 완전한 URL을 포함한 요청을 다시 보낸다. (303 or 307 상태 코드)
  • 부하 균형. 과부화된 서버가 요청을 받으면, 서버는 클라이언트를 좀 덜 부하가 걸린 서버로 리다이렉트할 수 있다. (303 or 307 상태 코드)
  • 친밀한 다른 서버가 있을 때, 즉 서버는 클라이언트를 그 클라이언트에 대한 정보를 갖고 있는 다른 서버로 리다이렉트할 수 있다. (303 or 307 상태 코드)
  • 디렉터리 이름 정규화. 클라이언트가 디렉터리 이름에 대한 URI를 요청하는데 끝에 빗금(/)을 빠뜨렸다면, 서버는 슬래시를 추가한 URL로 리다이렉트한다.

📌응답 보내기

받을 때와 마찬가지로 데이터를 보낼 때도 비슷한 이슈에 직면한다! 서버는 여러 클라이언트에 대해많은 커넥션을 가질 수 있다. 그들 중 일부는 아무것도 안하고 있는 상태이고, 일부는 서버로 데이터를 보내고 있으며, 또 다른 일부는 클라이언트로 돌려줄 응답 데이터를 실어 나르고 있을 것이다. 서버는 커넥션 상태를 추적해야 하며 지속적인 커넥션은 특별히 주의해서 다룰 필요가 있다. 비지속적이라면, 서버는 모든 메시지를 전송했을 때 자신쪽의 커넥션을 닫을 것이다.

📌로깅

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

문제

진짜 웹 서버가 하는일!
a) 요청 처리
b) 요청 메시지 수신
c) 로깅
d) 응답 보내기
e) 클라이언트 커넥션 수락
f) 리소스의 매핑과 접근
g) 응답 만들기

e -> b -> a -> f -> g -> d -> c

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

  1. 단일 스레드 웹 서버
  2. 멀티프로세스와 멀티스레드 웹 서버
  3. 다중 I/0서버
  4. 다중 멀티스레드 웹 서버

a) 몇몇 시스템은 자산의 컴퓨터 플랫폼에 올라와 있는 CPU 여러개의 이정을 살리기 위해 멀티스레딩과 다중화를 결합한다. 여러 개의 스레드는 각각 열려있는 커넥션을 감시하고 각 커넥션에 대해 조금씩 작업을 수행한다.
b) 여러 요청을 동시에 처리하기 위해 여러개의 프로세스 혹은 고효율 스레드를 할당한다. 그렇지만 많은 프로세스나 스레드는 너무 많은 메모리나 소비하기에 많은 멀티스레드 웹 서비스가 최대 개수에 제한을 건다.
c) 대량의 커넥션을 지원하기 위해, 많은 웹 서버는 다중 아키텍쳐를 채택했다. 모든 커넥션은 동시에 그 활동을 감시당한다. 커넥션에 대해 작은 양의 처리가 수행된다. 어떤 커넥션에 대해 작업을 수행하는 것은 그 커넥션에 실제로 해야 할 일이 있을 때뿐이다. 스레드와 프로세스는 유휴 상태의 커넥션에 매여 기다리느라 리소스를 낭비하지 않는다.
d) 단일 스레드 웹 서버는 한 번에 하나씩 요청을 처리한다. 구현하기 간단하지만 처리 도중에 모든 다른 커넥션은 무시된다. 오직 로드가 적은 서버나 type-o-serve와 같은 진단도구에서만 적당하다.

1 - d
2 - b
3 - c
4 - a

마무리

앞서 배웠던 내용들을 정리 해 주는 느낌의 5장이었습니다. 웹 서버라는 하나의 동작을 처음부터 끝까지 커넥션이라는 키워드와 함께 앞서 배운 키워드들과 함께 설명 해 주고 있었습니다.(큰 그림...?) 쭉쭉 읽어나가기 편한 장이어서 재밌게, 금방 읽었습니다. 다음장이 또 기대가 되네요!

profile
그냥 개인적으로 공부한 글들에 불과

0개의 댓글