5장: 웹 서버
- 웹 서버는 HTTP 요청을 처리하고 응답을 제공한다.
- 웹 서버는 HTTP 프로토콜을 구현하고, 이와 관련된 TCP 처리를 구현한 것이다. 웹 서버는 자신이 제공하는 리소스를 관리하고 웹 서버를 설정/통제/확장하기 위한 관리 기능을 제공한다.
- 웹 서버의 형태는 아래와 같다.
- 다목적 소프트웨어 웹 서버
- 임베디드 웹 서버
다목적 소프트웨어 웹 서버
- 네트워크에 연결된 표준 컴퓨터 시스템에서 동작하는 웹 서버이다.
- Microsoft 웹 서버, Apache 웹 서버, Nginx 등이 있다.
임베디드 웹 서버
- 일반 소비자용 제품에 내장될 목적으로 만들어진 작은 웹 서버이다.
웹 서버가 하는 일
- 커넥션 맺기: 클라이언트의 접속을 받아들이거나 닫는다.
- 요청 받기: HTTP 요청 메시지를 네트워크로부터 읽어들인다.
- 요청 처리하기: 요청 메시지를 해석하고 행동을 취한다.
- 리소스에 접근하기: 메시지에서 지정한 리소스에 접근한다.
- 응답 만들기: 올바를 헤더를 포함한 HTTP 응답 메시지를 작성한다.
- 응답 보내기: 응답을 클라이언트에게 돌려준다.
- 트랜잭션 로그 남기기: 로그 파일에 트랜잭션 완료에 대한 기록을 남긴다.
1단계: 클라이언트 커넥션 수락
- 클라이언트가 이미 서버에 대해 열려있는 지속적 커넥션을 갖고 있다면 해당 커넥션을 사용할 수 있다.
- 새 커넥션 다루기
- 클라이언트가 웹 서버에 TCP 커넥션을 요청하면 웹 서버는 커넥션을 맺고 TCP 커넥션에서 IP 주소를 추출하여 클라이언트를 확인한다.
- 커넥션이 맺어지고 받아들여지면 서버는 그 커넥션을 커넥션 목록에 추가한다.
- 웹 서버는 어떤 커넥션이든 거절하거나 즉시 닫을 수 있다.
- 클라이언트 호스트명 식별
- 대부분의 웹 서버는 역방향 DNS(reverse DNS)를 사용해 클라이언트 IP주소를 클라이언트 호스트명으로 변환하도록 설정되어 있다. 이를 호스트명 룩업(hostname lookup)이라고 한다.
- ident를 통해 클라이언트 사용자 알아내기
- IETF ident 프로토콜은 서버에게 어떤 사용자 이름이 HTTP 커넥션을 초기화했는지 찾아낼 수 있도록 한다.
- 클라이언트가 ident 프로토콜을 지원한다면 결과 반환을 위해 TCP 113 포트를 listen한다.
- 조직 내부에서는 잘 사용하지만 공공 인터넷에서는 잘 동작하지 않는다.
2단계: 요청 메시지 수신
- 커넥션에 데이터가 도착하면 웹 서버는 네트워크 커넥션에서 그 데이터를 읽어들이고 파싱하여 요청 메시지를 구성한다.
- 요청 메시지를 파싱하는 과정은 아래와 같다.
- 요청줄을 파싱해 요청 메서드, 지정된 리소스의 식별자(URI), 버전 번호를 찾는다.
- 메시지 헤더들을 읽는다.
- 헤더의 끝을 의미하는 CRLF로 끝나는 빈 줄이 존재한다면 찾아낸다.
- 요청 본문이 있다면 읽어들인다.
- 네트워크 커넥션은 언제라도 무효화될 수 있기 때문에, 웹 서버는 파싱해서 이해하는 것이 가능한 수준의 분량을 확보할 때까지 데이터를 네트워크로부터 읽어 메시지 일부분을 메모리에 임시로 저장해 둘 필요가 있다.
커넥션 입력/출력 처리 아키텍처
- 단일 스레드 웹 서버는 한 번에 하나씩 요청을 처리한다.
- 멀티프로세스와 멀티스레드 웹 서버는 여러 요청을 동시에 처리하기 위해 여러 개의 프로세스 혹은 고효율 스레드를 할당한다. 커넥션이 들어오면 스레드/프로세스를 할당한다.
- 다중 I/O 서버는 커넥션을 다중화하고 모든 커넥션이 활동을 감시당한다. 커넥션 상태가 바뀌면 그 커넥션에 대해 작은 양의 처리가 수행된다. 처리가 완료되면 그 커넥션은 다음번 상태 변경을 위해 열린 커넥션 목록으로 돌아간다.
- 다중 멀티스레드 웹 서버는 멀티코어 CPU 이점을 살리기 위해 멀티스레딩과 다중화를 결합하는 방식이다. 여러 개의 스레드는 각각 열려 있는 커넥션을 감시하고 각 커넥션에 대해 조금씩 작업을 수행한다.
3단계: 요청 처리
- 웹 서버가 요청을 받으면 서버는 요청으로부터 메서드, 리소스, 헤더, 본문을 얻어내 처리한다.
4단계: 리소스의 매핑과 접근
- 웹 서버는 리소스 서버이다.
- 미리 만들어진 정적 컨텐츠와 더불어 서버 위에서 동작하는 리소스 생성 애플리케이션을 통해 만들어진 동적 컨텐츠도 제공한다.
- docroot
- 리소스 매핑의 가장 단순한 형태로 요청 URI를 웹 서버의 시스템 내부 파일 이름으로 사용하는 방식이 있다. 일반적으로 웹 서버 파일 시스템의 특별한 폴더 docroot를 웹 컨텐츠를 위해 예약해둔다.
- 가상 호스팅된 docroot
- 가상 호스팅 웹 서버는 각 사이트에 분리된 문서 루트를 주는 방법으로 한 웹 서버에서 여러 개의 웹 사이트를 호스팅한다. 가상 호스팅 웹 서버는 URI나 Host 헤더에서 얻은 IP 주소나 호스트명을 이용해 올바른 문서 루트를 식별한다.
- 사용자 홈 디렉토리 docroot
- 사용자들이 한 대의 웹 서버에서 각자의 개인 웹 사이트를 만들 수 있도록 하는 것이다.
동적 컨텐츠 리소스 매핑
- 요청한 리소스가 동적 리소스라면 WAS가 그에 대한 생성 프로그램이 어디에 있는지, 어떻게 실행하는지 알려줄 수 있어야 한다.
- 서버사이드 인클루드(Server-Side Include, SSI)
- 어떤 리소스가 SSI를 포함한다면 서버는 그 리소스의 컨텐츠를 클라이언트에게 보내기 전에 처리한다.
- 컨텐츠에 변수 이름이나 내장 스크립트가 있는지 검사하고 치환된다.
- 어떤 리소스가 SSI를 포함한다면 서버는 그 리소스의 컨텐츠를 클라이언트에게 보내기 전에 처리한다.
- 웹 서버는 각 리소스에 접근 제어를 할당할 수 있다.
5단계: 응답 만들기
- 서버가 리소스를 식별하면 서버는 요청 메서드로 서술되는 동작을 수행한 뒤 응답 메시지를 반환한다.
응답 엔티티
- 만약 트랜잭션이 응답 본문을 생성한다면 그 내용을 응답 메시지와 함께 돌려보낸다. 본문이 있는 응답 메시지는 주로 다음을 포함한다.
- Content-Type: 응답 본문의 MIME 타입 헤더
- Content-Length: 응답 본문의 길이 헤더
- 실제 응답 본문 내용
MIME 타입 결정
- 웹 서버는 응답 본문의 MIME 타입을 결정해야 한다.
- mime.types: 파일 이름 확장자 사용, 확장자별 MIME 타입이 담겨 있는 파일 확인
- 매직 타이핑(Magic Typing): 파일이 표준 확장자 없이 지어진 경우 파일 내용을 검사해 알려진 패턴에 대한 테이블에 해당하는 패턴 탐색
- 유형 명시(Explicit Typing): 파일 확장자나 내용에 상관없이 타입 명시
- 유형 협상(Type negotiation): 한 리소스가 여러 종류의 문서 형식에 속하도록 설정 가능
리다이렉션
- 웹 서버는 요청을 수행하기 위해 브라우저가 다른 곳으로 가도록 리다이렉트할 수 있다.
- 영구히 리소스가 옮겨진 경우: 301 Moved Permanently
- 임시로 리소스가 옮겨진 경우: 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
- 디렉토리 이름 정규화: /을 빠트린 경우 상대 경로가 정상 작동하도록 올바른 URI로 리다이렉트
6단계: 응답 보내기
- 요청을 받을 때와 마찬가지로 커넥션 이슈가 발생한다.
- 서버는 커넥션 상태를 추적해야 하며 지속 커넥션을 주의해서 다뤄야 한다.
7단계: 로깅
- 웹 서버는 트랜잭션이 완료되었을 때 어떻게 수행되었는지에 대한 로그를 로그 파일에 기록한다.
6장: 프락시
- 웹 프락시 서버는 중개자이다.
- 프락시는 클라이언트와 서버 사이에 위치하여 그 사이의 HTTP 메시지를 정리하는 중개인처럼 동작한다.
웹 중개자
- 웹 프락시 서버는 클라이언트 입장에서 트랜잭션을 수행하는 중개인이다.
- HTTP 프락시 서버는 웹 서버이기도 하고 웹 클라이언트이기도 하다.
- HTTP 클라이언트의 요청을 받으므로 웹 서버처럼 요청과 커넥션을 적절히 다루고 응답을 돌려줘야 한다.
- 요청을 서버로 보내므로 요청을 보내고 응답을 받는 올바른 HTTP 클라이언트처럼 동작해야 한다.
개인 프락시와 공개 프락시
- 프락시 서버는 하나의 클라이언트가 독점적으로 사용할 수도 있고 여러 클라이언트가 공유할 수도 있다.
- 공용 프락시
- 대부분의 프락시는 공용 프락시이다. 중앙 집중형 프락시를 관리하는 게 비용 효율이 높고 쉽다.
- 개인 프락시
- 주로 클라이언트 컴퓨터에서 직접 실행되는 형태가 있다.
프락시 vs 게이트웨이
- 프락시는 같은 프로토콜을 이용하는 둘 이상의 애플리케이션을 연결한다.
- 게이트웨이는 서로 다른 프로토콜을 사용하는 둘 이상의 애플리케이션을 연결한다. 클라이언트와 서버가 서로 다른 프로토콜로 말하더라도 서로간의 트랜잭션을 완료할 수 있도록 해주는 프로토콜 변환기처럼 동작한다.
프락시를 사용하는 이유
- 보안을 개선하고 성능을 높여주며 비용을 절약할 수 있다.
- 어린이 필터
- 성인 컨텐츠를 차단하는 필터링 프락시
- 문서 접근 제어자
- 많은 웹 서버들과 웹 리소스에 대한 단일한 접근 제어 전략을 구현하고 감사 추적
- 보안 방화벽
- 조직 안에 들어오거나 나가는 응용 레벨 프로토콜 흐름을 네트워크의 한 지점에서 통제
- 후크: 웹이나 이메일 프락시가 사용하는 바이러스 제거 프락시
- 웹 캐시
- 자주 요청되는 문서의 로컬 사본을 관리해 빠르게 제공, 느리고 비싼 인터넷 커뮤니케이션 감소
- 대리 프락시(Surrogate)
- 대리/리버스 프락시는 웹 서버인 것처럼 위장해 진짜 웹 서버 요청을 받음, 요청받은 컨텐츠 위치를 찾아내기 위해 다른 서버와 커뮤니케이션
- 서버 가속기: 공용 컨텐츠에 대한 느린 웹 서버 성능 개선
- 컨텐츠 라우터
- 인터넷 트래픽 조건, 컨텐츠 종류에 따라 요청을 특정 웹 서버로 유도
- 트랜스코더
- 서버 컨텐츠를 클라이언트에게 전달하기 전에 본문 포맷 수정
- 익명화 프락시(Anonymizer)
- HTTP에서 신원을 식별할 수 있는 특성(클라이언트 IP 주소, From 헤더, Referer 헤더, 쿠키, URI 세션 아이디 등)을 제거해 개인정보 보호, 익명성 보장
프락시의 배치
프락시 서버 배치
- 출구(Egress) 프락시
- 로컬 네트워크의 출구에 배치 - 필터링 등
- 접근/입구 프락시
- ISP 접근 지점에 배치 - 속도 개선/인터넷 대역폭 비용 감소를 위해 문서 사본 저장 등
- 대리(리버스) 프락시
- 네트워크 말단에 존재하는 웹 서버들의 바로 앞에 배치 - 웹 서버로 향하는 모든 요청을 처리하고 필요할 때만 웹 서버에 자원 요청
- 네트워크 교환 프락시
- 트래픽 혼잡 완화, 흐름 감시
프락시 계층
- 프락시들은 프락시 계층이라는 연쇄를 구성할 수 있다.
- 프락시 서버들은 부모-자식 관계를 갖는다.
- 서버에 가까운 쪽이 인바운드 프락시/부모이다.
- 클라이언트에 가까운 쪽이 아웃바운드 프락시/자식이다.
- 프락시 계층 컨텐츠 라우팅
- 프락시 서버는 여러 판단 근거에 의해 메시지를 다양하고 유동적인 프락시 서버와 원 서버 집합에게 보낼 수 있다.
- 동적 부모 선택의 예는 아래와 같다.
- 부하 균형: 부모들의 작업량 수준에 근거해 선택
- 지리적 인접성에 근거한 라우팅: 원 서버의 지역을 담당하는 부모 선택
- 프로토콜/타입 라우팅: URI에 근거해 선택
- 유료 서비스 가입자 라우팅: 대형 캐시/성능 개선 등을 위한 압축 엔진으로 라우팅되는 경우
프락시의 트래픽 처리
- 클라이언트 트래픽이 프락시로 가도록 만드는 방법은 아래와 같다.
- 클라이언트 수정
- 많은 웹 클라이언트가 수동/자동 프락시 설정을 지원한다.
- 클라이언트가 프락시를 사용하도록 설정되어 있다면 클라이언트는 요청을 프락시 서버로 보낸다.
- 네트워크 수정
- 인터셉트 프락시: 클라이언트가 모르고 간섭할 수 없는 상태에서 네트워크 인프라를 가로채 웹 트래픽이 프락시로 가도록 조정
- DNS 이름공간 수정
- 대리 프락시는 웹 서버 이름과 IP 주소를 자신이 직접 사용한다.
- DNS 이름 테이블을 수동으로 편집하거나 사용할 적절한 프락시나 서버를 계산해주는 특별한 동적 DNS 서버를 이용해 조정할 수 있다.
- 실제 서버의 IP 주소와 이름은 변경되고 대리 프락시가 기존의 IP 주소와 이름을 부여받는다.
- 대리 프락시는 웹 서버 이름과 IP 주소를 자신이 직접 사용한다.
- 웹 서버 수정
- HTTP 리다이렉션 명령을 클라이언트에게 돌려줌으로써 요청을 프락시로 리다이렉트한다.
- 리다이렉트를 받는 즉시 클라이언트는 프락시와의 트랜잭션을 시작한다.
클라이언트 프락시 설정
수동 설정
- 프락시를 사용하겠다고 명시적으로 설정한다.
- 모든 컨텐츠를 위해 단 하나의 프락시 서버만을 지정할 수 있다.
- 장애 시 대체 작동에 대한 지원이 없다.
브라우저 기본 설정
- 브라우저를 소비자에게 전달하기 전에 프락시를 미리 설정해 놓을 수 있다.
프락시 자동 설정(Proxy Auto-configuration, PAC)
- 자바스크립트 PAC 파일에 대한 URI를 제공해 설정한다.
- 프락시 설정을 상황에 맞게 계산해주는 작은 자바스크립트 프로그램이다.
WPAD 프락시 발견
- 대부분의 브라우저는 자동설정 파일을 다운받을 수 있는 설정 서버를 자동으로 찾아주는 웹 프락시 자동발견 프로토콜(Web Proxy Autodiscovery Protocol)을 제공한다.
- WPAD는 여러 발견 매커니즘의 상승 전략을 이용해 브라우저에게 알맞은 PAC 파일을 자동으로 찾아주는 알고리즘이다.
- WPAD 프로토콜이 구현된 클라이언트는 아래 일을 한다.
- PAC URI를 찾기 위해 WPAD를 사용한다.
- 주어진 URI에서 PAC 파일을 가져온다.
- 프락시 서버를 알아내기 위해 PAC 파일을 실행한다.
- 알아낸 프락시 서버를 이용해 요청을 처리한다.
프락시 요청의 특징
프락시 URI vs 서버 URI
- 클라이언트가 웹 서버로 요청을 보낼 때의 URI는 스킴, 호스트, 포트번호가 없는 부분 URI이다.
- 클라이언트가 프락시로 요청을 보낼 때의 URI는 완전한 URI이다.
- 프락시는 목적지 서버와 커넥션을 맺어야 하기 때문에 서버 이름을 알 필요가 있다.
- 프락시 기반 게이트웨이는 스킴과 연결하기 위해 URI 스킴을 알 필요가 있다.
- 프락시의 스킴/호스트/포트번호 누락 문제는 가상 호스팅 웹 서버에서도 발생한다. 가상으로 호스팅되는 웹 서버는 부분 URI만 가지고 해당 요청이 접근하려는 웹 사이트의 호스트명을 알 수 없다.
- 가상 호스팅 웹 서버는 호스트와 포트 정보가 담겨 있는 Host 헤더를 요구한다.
인터셉트 프락시는 부분 URI 사용
- 몇몇 프락시는 클라이언트에게 보이지 않을 수 있기 때문에 클라이언트가 항상 자신이 프락시와 대화하고 있음을 아는 것은 아니다.
- 클라이언트가 대리 프락시나 인터셉트 프락시를 지나는 경우 클라이언트는 자신이 웹 서버와 대화하고 있다고 생각하고 부분 URI를 보낸다.
- 대리 프락시(리버스 프락시)는 원 서버의 호스트명, IP 주소를 사용해 원 서버를 대신하는 프락시 서버이다.
- 인터셉트 프락시는 네트워크 흐름에서 클라이언트 → 서버 트래픽을 가로채 캐시된 응답을 돌려주는 등의 역할을 하는 프락시 서버이다.
프락시는 프락시 요청/서버 요청 둘 다 다룸
- 다목적 프락시 서버는 요청 메시지의 완전한 URI와 부분 URI를 모두 지원해야 한다.
- 완전한 URI와 부분 URI 사용 규칙은 아래와 같다.
- 완전한 URI가 주어지면 프락시는 그것을 사용해야 한다.
- 부분 URI이 주어지고 Host 헤더가 있다면 원 서버 이름, 포트번호를 알아내야 한다.
- 부분 URI가 주어졌으나 Host 헤덕 없다면 아래 방법으로 원 서버 주소를 알아내야 한다.
- 대리 프락시라면 프락시에 실제 서버 주소, 포트번호가 설정되어 있을 수 있다.
- 이전에 인터셉트 프락시가 가로챘던 트래픽을 받았고 원 주소와 포트번호를 사용할 수 있도록 설정했다면 그 값을 사용할 수 있다.
- 위 방법이 모두 실패한다면 프락시는 원 서버를 알아낼 수 없다. 에러 메시지를 반환한다.
전송 중 URI 변경
- 일반적으로 프락시 서버는 가능한 한 관대해야 한다. 사소한 URI 변경도 다운스트림 서버와 상호운용성 문제를 일으킬 수 있다.
URI 클라이언트 자동 확장/호스트명 분석
- 브라우저는 프락시 존재 여부에 따라 요청 URI를 다르게 분석한다.
- 프락시 없는 URI 분석(URI Resolution)
- 브라우저는 명시적인 프락시가 존재하지 않는 경우 부분 호스트명을 자동으로 확장한다.
- 명시적인 프락시를 사용할 때의 URI 분석
- 명시적 프락시가 있는 경우 부분 호스트명을 자동으로 확장하지 않는다.
메시지 추적
Via 헤더
- 메시지가 지나는 각 중간 노드(프락시나 게이트웨이)의 정보를 나열한다.
- 메시지 전달 추적, 메시지 루프 진단, 요청-응답 과정에 관여하는 모든 메시지 발송자들의 프로토콜을 진단하기 위해 사용한다.
- 프락시는 네트워크 라우팅 루프를 탐지하기 위해 Via 헤더를 사용할 수 있다.
- 응답의 Via 헤더는 거의 언제나 요청의 Via 헤더와 반대이다. 즉 요청이 A, B, C였다면 응답은 C, B, A가 된다.
- Server 헤더와 Via 헤더
- Server 응답 헤더 필드는 원 서버에 의해 사용되는 소프트웨어를 알려준다.
TRACE 메서드
- HTTP/1.1의 TRACE 메서드는 요청 메시지를 프락시 연쇄를 따라가며 어떤 프락시를 지나가고 어떻게 각 프락시가 요청 메시지를 수정하는지 관찰/추적한다.
- TRACE 요청이 목적지 서버에 도착하면 서버는 전체 요청 메시지를 응답 본문에 포함시켜 송신자에게 그대로 돌려보낸다.
- Max-Forwards 요청 헤더 필드는 요청 메시지가 몇 번 더 다음 홉으로 전달될 수 있는지를 정의한다. 무한 루프 연쇄를 테스트하거나 연쇄 중간의 특정 프락시 효과 검증시 유용하다.
- 모든 프락시와 게이트웨이는 Max-Forwards를 지원해야 한다.
프락시 인증
- 프락시는 접근 제어 장치로서 제공될 수 있다.
- 제한 컨텐츠에 대한 요청이 프락시 서버에 도착하면 프락시는 접근 자격을 요구하는 407 Proxy Authorization Required 상태 코드를 Proxy-Authenticate 헤더 필드와 함께 반환할 수 있다.
프락시 상호운용성
지원하지 않는 헤더와 메서드
- 프락시는 이해할 수 없는 헤더 필드는 반드시 그대로, 상대적인 순서도 유지해 전달해야 한다.
- 프락시가 어떤 메서드를 모른다면 가능한 다음 홉으로 전달하려 시도해야 한다.
OPTIONS: 어떤 기능을 지원하는지 알아보기
- OPTIONS 메서드는 서버나 특정 리소스가 어떤 기능을 지원하는지 클라이언트에게 알려준다.
- Allow 엔티티 헤더 필드는 요청 URI에 의해 식별되는 자원에 대해 지원되는 메서드들이나 서버가 지원하는 모든 메서드를 열거한다.
7장: 캐시
- 캐시는 다음과 같은 혜택을 준다.
- 복수의 클라이언트가 자주 사용되는 원 서버 페이지에 접근할 때 서버는 같은 문서를 클라이언트들에게 각각 한 번씩 전송하게 된다. 첫 번째 응답을 캐시에 저장하면 원 서버의 트래픽을 줄일 수 있다.
- 많은 네트워크가 원격 서버보다 로컬 네트워크 클라이언트에 더 넓은 대역폭을 제공한다. 클라이언트가 서버에 접근할 때의 속도는 그 경로에 있는 가장 느린 네트워크의 속도와 같다. 따라서 캐시에 리소스를 저장해 사본을 가져온다면 대역폭 방목을 줄일 수 있다.
- 캐시는 갑작스러운 트래픽 급증에 대처하기 위해 특히 중요하다.
- 캐시를 사용해 물리적인 거리를 줄일 수 있다.
적중과 부적중
- 캐시는 모든 문서의 사본을 저장하지 않는다.
- 캐시 적중(cache hit)은 캐시에 요청이 도착했을 때 그에 대응하는 사본이 있는 경우이다. 사본이 없다면 그냥 원 서버로 전달된다(캐시 부적중miss).
- HTTP는 클라이언트에게 응답이 캐시 적중이었는지 부적중이었는지 알리는 방법을 제공하지 않는다.
- 응답의 Date 헤더를 현재 시각과 비교해 응답 생성일이 더 오래되었다면 응답이 캐시임을 알 수 있다.
- 응답의 Age 헤더로 응답이 얼마나 오래되었는지 알 수 있다.
재검사(Revalidation)
- 원 서버 컨텐츠는 변경될 수 있으므로 캐시는 본인이 갖고 있는 사본이 최신인지 점검해야 한다.
- 대부분의 캐시는 클라이언트가 사본을 요청했으며 그 사본이 재검사할 만큼 충분히 오래된 경우에만 재검사를 수행한다.
- 캐시는 재검사를 위해 원 서버에 아주 작은 재검사 요청을 보낸다.
- 컨텐츠가 변경되지 않았다면 서버는 아주 작은 304 Not Modified 응답을 보낸다.
- 캐시는 사본이 유효함을 알게 된 후 사본을 클라이언트에게 제공한다(재검사 적중/느린 적중).
- 속도: 순수 캐시 적중 < 재검사 적중 < 캐시 부적중
- 캐시된 사본과 원 서버 객체와 다르다면 서버는 컨텐츠 전체와 평범한 200 Ok응답을 클라이언트에게 보낸다(재검사 부적중).
- 서버 객체가 삭제되었다면 서버는 404 Not Found를 보내며 캐시는 사본을 삭제한다(객체 삭제).
적중률
- 캐시가 요청을(서버 대신) 처리하는 비율을 캐시 적중률 또는 문서 적중률이라고 한다.
- 문서의 개수가 아니라 바이트 단위로 적중률을 측정하는 것을 바이트 적중률이라고 한다. 바이트 적중률을 개선하면 대역폭 절약을 최적화할 수 있다.
캐시 토폴로지
개인 전용 캐시private cache
- 한 명의 사용자에게만 할당되는 캐시이다.
- 웹브라우저는 개인 전용 캐시를 내장한다.
공용 프락시 캐시(캐시 프락시 서버/프락시 캐시)
- 여러 사용자가 접근 가능한 캐시이다.
- 자주 찾는 객체를 단 한 번만 가져와 모든 요청에 대해 공유된 사본을 제공한다.
프락시 캐시 계층
- 클라이언트에 더 가깝고 작은 캐시에서 부적중이 발생하면 더 큰 부모 캐시가 그 트래픽을 처리하도록 하는 계층 구조를 사용한다.
- 단순한 캐시 계층 대신 복잡한 캐시망을 만들어 어떤 부모 캐시와 대화할 것인지를 동적으로 결정한다.
- 선택적 피어링을 지원하는 캐시는 형제 캐시라고 불린다. HTTP는 인터넷 캐시 프로토콜(ICP)이나 하이퍼텍스트 캐시 프로토콜(HTCP) 등을 이용해 형제 캐시를 지원한다.
캐시 처리 단계
- 웹 캐시의 기본적인 동작은 아래와 같다.
- 요청 받기: 캐시는 네트워크로부터 도착한 요청 메시지를 읽는다.
- 파싱: 캐시는 메시지를 파싱하여 URL과 헤더를 추출한다.
- 검색: 캐시는 로컬 복사본이 있는지 검사하고, 사본이 없다면 사본을 받아온(뒤 로컬에 저장한)다.
- 로컬 복사본은 메모리/디스크/근처 컴퓨터에 있을 수도 있다. 빠른 알고리즘을 사용해 검색을 수행한다.
- 캐시된 객체는 서버 응답 본문/헤더, 몇몇 메타데이터를 포함한다.
- 신선도 검사: 캐시는 캐시된 사본이 충분히 신선한지 검사하고, 신선하지 않다면 변경사항이 있는지 서버에게 물어본다.
- 응답 생성: 캐시는 새로운 헤더와 캐시된 본문으로 응답 메시지를 만든다.
- 원 서버의 응답 헤더를 토대로 응답 헤더를 생성한다. 이 헤더들은 캐시에 의해 수정되고 늘어난다.
- 캐시는 클라이언트에 맞게 헤더를 조정해야 한다.
- 발송: 캐시는 네트워크를 통해 응답을 클라이언트에게 돌려준다.
- 로깅: 선택적으로 캐시는 로그파일에 트랜잭션에 대해 서술한 로그 하나를 남긴다.
8장: 통합점
게이트웨이
- 게이트웨이는 리소스와 애플리케이션을 연결하는 역할을 한다.
- 요청을 받고 응답을 보내는 포털처럼 동작한다. 동적 컨텐츠를 생성하거나 데이터베이스에 질의를 보낼 수 있다.
- HTTP 트래픽을 다른 프로토콜로 자동으로 변환하여 HTTP 클라이언트가 다른 프로토콜을 알 필요 없이 서버에 접속할 수 있도록 한다.
- 웹 게이트웨이는 한쪽에서는 HTTP로 통신하고 다른 쪽에서는 HTTP가 아닌 다른 프로토콜로 통신한다.
- 클라이언트 프로토콜/서버 프로토콜 형식으로 표현한다.
- 서버 측 게이트웨이: 클라이언트와 HTTP로 통신, 서버와 외래 프로토콜로 통신
- 클라이언트 측 게이트웨이: 클라이언트와 외래 프로토콜로 통신, 서버와 HTTP로 통신
서버 측 웹 게이트웨이: HTTP/*
- 서버 측 웹 게이트웨이는 클라이언트로부터 HTTP 요청이 원 서버 영역으로 들어오는 시점에 그 요청을 외래 프로토콜로 전환한다.
- 게이트웨이가 요청을 해당하는 프로토콜에 맞게 요청하고 응답을 받는다.
- 게이트웨이는 객체를 받는 대로 HTTP 응답에 실어 클라이언트에게 전송한다.
서버 측 보안 게이트웨이: HTTP/HTTPS
- 모든 웹 요청을 암호화할 때 HTTP/HTTPS 인바운드 보안 게이트웨이를 사용할 수 있다.
클라이언트 측 보안 가속 게이트웨이: HTTPS/HTTP
- 웹 서버 앞단에 위치하고 보이지 않는 인터셉트 게이트웨이나 리버스 프락시 역할을 한다.
- HTTPS 트래픽을 받아 복호화하고 웹 서버로 보낼 일반 HTTP 요청을 만든다.
- 원 서버보다 효율적으로 보안 트래픽을 복호화하여 서버 부하를 줄일 수도 있다.
- 게이트웨이와 원 서버 간 암호화하지 않은 트래픽을 전송하기 때문에 그 사이 네트워크가 안전한지 확인한 다음 사용해야 한다.
리소스 게이트웨이
- 리소스 게이트웨이는 웹 서버가 애플리케이션과 통신하는 수단이다.
- 게이트웨이의 가장 일반적 형태인 애플리케이션 서버는 목적지 서버와 게이트웨이를 한 개의 서버로 결합한다.
- 애플리케이션 서버는 게이트웨이의 API(Application Programming Interfac)를 통해 요청을 서버에서 동작하고 있는 애플리케이션에 전달한다.
공용 게이트웨이 인터페이스
- CGI(Common Gateway Interface)는 최초의 확장 서버이자 지금까지도 가장 널리 쓰이는 서버 확장이다.
- CGI는 특정 URL에 대한 HTTP 요청에 따라 프로그램을 실행하고, 프로그램의 출력을 수집하고, HTTP 응답으로 회신하는 데 웹 서버가 사용하는 표준화된 인터페이스 집합이다.
터널
- 웹 터널은 HTTP 프로토콜을 지원하지 않는 애플리케이션에 HTTP 애플리케이션을 사용해 접근하는 방법을 제공한다.
- 웹 터널을 사용하는 가장 일반적인 경우는 HTTP 커넥션 안에 HTTP가 아닌 트래픽을 얹는 경우이다.
- 웹 트래픽만을 허락하는 방화벽이 있더라도 HTTP가 아닌 트래픽을 전송할 수 있다.
HTTP 터널 커넥션 맺기
- HTTP의 CONNECT 메서드(확장)를 사용해 커넥션을 맺을 수 있다.
- CONNECT 메서드는 터널 게이트웨이가 임의의 목적 서버와 포트에 TCP 커넥션을 맺고 클라이언트-서버 간 데이터를 무조건 전달하기를 요청한다.
SSL 터널링
- 터널을 사용하면 SSL 트래픽을 HTTP 커넥션으로 전송하여 80포트의 HTTP만을 허용하는 방화벽을 통과시킬 수 있다.
- 보안 SSL 트래픽이 방화벽을 통과하는 데 유용하게 사용될 수 있지만 악의적인 트래픽이 사내로 유입되는 경로가 될 수도 있다.
- 터널의 오용을 최소화하기 위해 게이트웨이는 443같이 잘 알려진 특정 포트만을 터널링할 수 있게 허용해야 한다.
릴레이
- HTTP 릴레이는 HTTP 명세를 완전히 준수하지는 않는 간단한 HTTP 프락시다.
- 커넥션을 맺은 뒤 바이트를 맹목적으로 전달한다.
- 단순 맹목적 릴레이를 사용할 때 생기는 일반적인 문제는 Connection 헤더를 제대로 처리하지 못해 keep-alive 커넥션이 행(hang)에 걸리는 문제가 있다.
- 릴레이가 Connection 헤더(홉-홉 사이에서만 사용하는 헤더이므로 도착 홉에서 처리해야 함)를 이해하지 못하고 서버로 그대로 전달한다.
- 서버는 Connection: keep-alive를 받기 때문에 커넥션을 끊지 않고 계속 대기한다.
- 릴레이는 Connection: keep-alive를 이해하지 못했기 때문에 커넥션이 끊기기를 기다리며 계속 커넥션을 맺고(hang) 있는다.
- 클라이언트가 다음 요청을 보내도 릴레이는 같은 커넥션으로 다른 요청이 오는 것을 예측하지 못하기 때문에 아무런 작업도 진행되지 않는다.
- 위와 같은 여러 문제를 예방하기 위해 HTTP를 제대로 준수하는 프락시를 사용하는 것이 좋다.
'공부 > 책' 카테고리의 다른 글
| [HTTP 완벽 가이드] 5부 학습 (0) | 2025.05.29 |
|---|---|
| [HTTP 완벽 가이드] 3부 학습 (0) | 2025.05.23 |
| [HTTP 완벽 가이드] 1부 학습 (0) | 2025.05.06 |
| [단위 테스트] 학습 (0) | 2025.01.24 |