웹 서버
외관





웹 서버(영어: web server)는 웹 콘텐츠를 배포하기 위해 만들어진 네트워크 프로토콜인 HTTP 또는 그 보안 버전인 HTTPS를 통해 요청을 수락하는 컴퓨터 소프트웨어이다. 일반적으로 웹 브라우저나 웹 크롤러인 사용자 에이전트는 HTTP를 사용하여 웹 페이지 또는 기타 웹 리소스를 요청함으로써 통신을 시작하며, 서버는 해당 리소스의 콘텐츠나 HTTP 상태 코드를 포함한 응답을 보낸다. 웹 서버는 설정에 따라 사용자 에이전트로부터 전송된 리소스를 수락하고 저장할 수도 있다.[1][2][3][4][5]
웹 서버를 실행하는 데 사용되는 하드웨어는 처리해야 할 요청의 양에 따라 달라진다. 범위의 하단에는 작은 웹 서버를 구성 인터페이스로 실행하는 라우터와 같은 임베디드 시스템이 있다. 트래픽이 많은 인터넷 웹사이트는 고속 컴퓨터 랙에서 실행되는 수백 대의 서버로 요청을 처리할 수 있다.[6]
웹 서버에서 전송되는 리소스는 웹 서버에서 이용 가능한 기존의 파일 (정적 콘텐츠)일 수도 있고, 서버 소프트웨어와 통신하는 다른 프로그램에 의해 요청 시점에 생성된 것(동적 콘텐츠)일 수도 있다. 전자는 대개 더 빠르게 제공될 수 있고 반복되는 요청에 대해 더 쉽게 웹 캐시될 수 있는 반면, 후자는 더 광범위한 애플리케이션을 지원한다.
일반적인 컴퓨터 간 통신을 위해 HTTP를 기본으로 사용하는 REST 및 SOAP과 같은 기술, 그리고 WebDAV 확장에 대한 지원은 웹 서버의 적용 범위를 인간이 읽을 수 있는 페이지를 제공한다는 원래의 목적을 훨씬 넘어 확장시켰다.
역사
[편집]
이는 웹 서버 프로그램의 매우 간략한 역사이므로, 일부 정보는 웹 브라우저, 월드 와이드 웹, 인터넷의 역사와 필연적으로 겹친다. 따라서 명확성과 이해를 돕기 위해 아래에 보고된 몇 가지 주요 역사적 정보는 위에서 언급한 하나 이상의 역사 관련 문서에서 발견되는 내용과 유사할 수 있다.[7]
초기 WWW 프로젝트 (1989–1991)
[편집]1989년 3월, 팀 버너스리 경은 과학자들 사이의 정보 교환을 용이하게 하기 위해 하이퍼텍스트 시스템을 사용하는 새로운 프로젝트를 자신의 고용주인 CERN에 제안했다. "HyperText and CERN"이라는 제목의 이 제안서는 의견을 구했고 여러 사람에게 읽혔다. 1990년 10월, 이 제안은 (공동 저자인 로베르 카이오와 함께) 재구성되고 보강되었으며, 마침내 승인되었다.[8][9][10]
1990년 말에서 1991년 초 사이, 이 프로젝트의 결과로 버너스리와 그의 개발자들은 넥스트 컴퓨터 워크스테이션에 설치된 NeXTSTEP OS에서 처음 실행되는 세 가지 프로그램과 함께 여러 소프트웨어 라이브러리를 작성하고 테스트했다.[11][12][10]
- 월드와이드웹이라 불리는 그래픽 웹 브라우저;
- 휴대용 라인 모드 브라우저;
- 나중에 CERN httpd로 알려진 웹 서버.
이 초기 브라우저들은 HTTP 0.9라는 이름의 새로운 기본 통신 프로토콜을 사용하여 웹 서버로부터 단순한 초기 형태의 HTML로 작성된 웹 페이지를 검색했다.
1991년 8월, 팀 버너스리는 WWW 기술의 탄생을 알리고 과학자들에게 이를 채택하고 개발하도록 장려했다.[13] 그 직후, 이 프로그램들과 그 소스 코드는 사용에 관심이 있는 사람들에게 공개되었다.[11] 소스 코드가 공식적으로 라이선스가 부여되거나 퍼블릭 도메인에 배치되지는 않았지만, CERN은 비공식적으로 사용자와 개발자가 이를 실험하고 발전시키는 것을 허용했다. 버너스리는 이러한 프로그램의 채택과 사용을 장려함과 동시에 다른 운영체제로의 이식을 시작했다.[10]
급격한 발전 (1991–1995)
[편집]1991년 12월, 유럽 밖 최초의 웹 서버가 (미국) SLAC에 설치되었다.[12] 이것은 웹 브라우저와 웹 서버 간의 대륙 간 웹 통신을 시작했기 때문에 매우 중요한 사건이었다.
1991~1993년 동안 CERN 웹 서버 프로그램은 www 그룹에 의해 지속적으로 개발되었으며, 한편 소스 코드의 가용성과 HTTP 프로토콜의 공개 사양 덕분에 다른 많은 웹 서버 구현이 개발되기 시작했다.
1993년 4월, CERN은 웹 소프트웨어의 세 가지 구성 요소(기본 라인 모드 클라이언트, 웹 서버, 공통 코드 라이브러리)가 그 소스 코드와 함께 퍼블릭 도메인에 공개되었다는 공식 성명을 발표했다.[14] 이 성명은 웹 서버 개발자들을 해당 소스 코드를 기반으로 하는 파생 저작물 개발과 관련된 모든 법적 문제(실제로는 존재하지 않았던 위협)로부터 자유롭게 했다.
1994년 초, 새로운 웹 서버 중 가장 주목할 만한 것은 다양한 유닉스 기반 OS에서 실행되는 NCSA httpd였으며, 이는 POST HTTP 메서드와 외부 프로그램과의 통신을 위한 CGI를 구현하여 동적으로 생성된 콘텐츠를 제공할 수 있었다. 이러한 기능은 (웹 서버로 데이터를 보내기 위해 HTML 폼을 관리할 수 있는) NCSA의 모자이크 브라우저의 멀티미디어 기능과 함께 출판 및 분산 컴퓨팅 애플리케이션을 위한 웹 기술의 잠재력을 강조했다.
1994년 하반기에 NCSA httpd의 개발은 정체되었고, 이에 따라 해당 서버에 관심이 있는 외부 소프트웨어 개발자, 웹마스터, 기타 전문직 종사자 그룹이 NCSA httpd 소스 코드가 퍼블릭 도메인으로 공개된 덕분에 패치를 작성하고 수집하기 시작했다. 1995년 초, 이러한 패치들이 모두 NCSA 소스 코드의 마지막 릴리스에 적용되었고, 여러 번의 테스트 끝에 아파치 HTTP 서버 프로젝트가 시작되었다.[17][18]
1994년 말, 오라클의 Netsite라는 새로운 상용 웹 서버가 특정 기능을 갖추고 출시되었다. 이는 넷스케이프, 그 다음으로 썬 마이크로시스템즈, 마지막으로 오라클에 의해 개발된 많은 유사 제품들 중 첫 번째였다.
1995년 중반, 마이크로소프트에 의해 윈도우 NT OS용 IIS 첫 번째 버전이 출시되었다. 이는 월드 와이드 웹 기술 분야에서 웹의 양쪽 측면(클라이언트와 서버)에서 핵심적인 역할을 해왔고 여전히 수행하고 있는 상용 개발자 및 공급업체의 진입을 의미했다.
1995년 하반기, CERN 및 NCSA 웹 서버는 이전 서버들보다 훨씬 더 빠른 개발 주기와 더 많은 기능, 더 많은 수정 사항, 더 나은 성능을 가진 새로운 웹 서버들의 광범위한 채택으로 인해 (전 세계 사용 비율 측면에서) 쇠퇴하기 시작했다.
폭발적인 성장과 경쟁 (1996–2014)
[편집]
1996년 말, 인터넷 도메인 네임을 소유하거나 웹사이트를 호스팅하고자 하는 모든 사람이 사용할 수 있는 알려진 웹 서버 소프트웨어 프로그램이 이미 50개가 넘었다.[20] 그중 다수는 수명이 짧았고 다른 웹 서버들로 대체되었다.
프로토콜 버전 HTTP/1.0(1996) 및 HTTP/1.1(1997, 1999)에 관한 RFC의 출판은 대부분의 웹 서버가 해당 표준을 (항상 완벽하게는 아니지만) 준수하도록 강제했다. TCP/IP 지속적 연결(HTTP/1.1)을 사용하려면 웹 서버가 허용되는 최대 동시 연결 수를 늘리고 확장성 수준을 개선해야 했다.
1996년에서 1999년 사이에 넷스케이프 엔터프라이즈 서버와 마이크로소프트의 IIS가 주요 상용 옵션으로 부상한 반면, 자유롭게 사용 가능한 오픈 소스 프로그램 중에서는 아파치 HTTP 서버가 (신뢰성과 많은 기능 덕분에) 선호되는 서버로서 선두를 유지했다.
그 당시에는 낮은 사용률에도 불구하고 최소한 2000년대 첫 10년까지 시장에서 가장 빠르고 확장성이 뛰어난 웹 서버 중 하나로 알려진 제우스라는 또 다른 상용 웹 서버가 있었다.
아파치는 1996년 중반부터 2015년 말까지 가장 많이 사용되는 웹 서버였으며, 몇 년간의 쇠퇴 후 처음에 IIS에, 그 다음에는 Nginx에 추월당했다. 이후 IIS는 아파치보다 훨씬 낮은 사용 비율로 떨어졌다(시장 점유율 참조).
2005~2006년부터 아파치는 새로운 성능 기능(예: 이벤트 MPM 및 새로운 콘텐츠 캐시)을 도입하여 속도와 확장성 수준을 개선하기 시작했다.[21][22] 이러한 새로운 성능 개선 사항은 초기에 실험적인 것으로 표시되었기 때문에 사용자들이 오랫동안 활성화하지 않았고, 그 결과 아파치는 상용 서버들의 경쟁, 그리고 무엇보다도 개발 초기부터 훨씬 뛰어난 성능을 달성했으며 당시 이미 잘 테스트된 고급 기능 목록을 제공할 수 있었던 다른 오픈 소스 서버들의 경쟁으로 인해 더욱 고통받았다.
2000년대 초반 몇 년이 지난 후, 다른 상용 및 경쟁력이 높은 웹 서버(예: LiteSpeed)뿐만 아니라 Hiawatha, Cherokee HTTP 서버, lighttpd, nginx, 그리고 상용 지원과 함께 제공되는 기타 파생 및 관련 제품들도 등장했다.
2007~2008년경, 대부분의 인기 있는 웹 브라우저는 이미지로 가득 찬 무거운 웹 페이지의 검색 속도를 높이고 웹 페이지의 양방향 이벤트 알림에 사용되는 동적 객체에 전용 지속적 연결이 부족한 문제를 완화하기 위해 (RFC-2616에서 권장하는) 이전 호스트 도메인당 2개의 지속적 연결 기본 제한을 호스트 도메인당 4, 6 또는 8개로 늘렸다.[23][24] 1년 이내에 이러한 변경은 평균적으로 웹 서버가 관리해야 하는 최대 지속적 연결 수를 거의 3배로 늘렸다. 이러한 추세(지속적 연결 수 증가)는 더 느린 웹 서버 앞단에 리버스 프록시를 채택하도록 강력한 추진력을 제공했으며, 많은 하드웨어 리소스(많은 CPU, RAM 및 빠른 디스크를 갖춘 값비싼 컴퓨터)를 요구하지 않고도 매우 높은 수의 동시 연결을 처리할 수 있는 속도와 능력을 보여줄 수 있는 새로운 웹 서버들에게 기회를 제공했다.[25]
새로운 도전 (2015년 이후)
[편집]2015년, RFC는 새로운 프로토콜 버전 [HTTP/2]를 게시했고, 새로운 사양의 구현이 전혀 간단하지 않았기 때문에 (사용률이 1%~2% 미만인) 덜 인기 있는 웹 서버 개발자들 사이에서 해당 새 프로토콜 버전에 대한 지원을 추가할지 여부에 대한 딜레마가 발생했다.[26][27]
실제로 HTTP/2를 지원하려면 많은 요소(실질적으로 항상 암호화된 연결 필요, 동일한 TCP 포트에서 HTTP/1.x와 HTTP/2 연결을 구별하는 기능, HTTP 메시지의 이진 표현, 메시지 우선순위, HTTP 헤더 압축, TCP/IP 하위 연결이라고도 하는 스트림 사용 및 관련 흐름 제어 등)로 인해 내부 구현에 급격한 변경이 필요했기 때문에, 일부 웹 서버 개발자들은 주로 다음과 같은 이유로 새로운 HTTP/2 버전을 지원하지 않기로 선택했다.[26][27]
- HTTP/1.x 프로토콜은 브라우저에서 매우 오랫동안(아마도 영원히) 지원될 것이므로 가까운 미래에 클라이언트와 서버 간의 비호환성은 없을 것이다.
- HTTP/2 구현은 2015년까지 존재하지 않았던 완전히 새로운 클래스의 소프트웨어 버그를 유발할 수 있는 압도적인 복잡성의 작업으로 간주되었으며, 따라서 새로운 프로토콜의 구현을 개발하고 테스트하는 데 상당한 투자가 필요했을 것이다.
- HTTP/2 지원 추가는 노력이 정당화될 경우 언제든지 향후에 수행할 수 있었다.
대신, 가장 인기 있는 웹 서버의 개발자들은 서둘러 새로운 프로토콜을 제공했는데, 이는 그들에게 그렇게 할 인력과 시간이 있었기 때문일 뿐만 아니라, 보통 SPDY 프로토콜에 대한 이전 구현을 출발점으로 재사용할 수 있었고 가장 많이 사용되는 웹 브라우저들이 같은 이유로 이를 매우 빠르게 구현했기 때문이다. 이러한 개발자들이 신속하게 행동하도록 유도한 또 다른 이유는 웹마스터들이 계속 증가하는 웹 트래픽의 압박을 느꼈고 TCP/IP 연결 수를 획기적으로 줄이고 호스팅된 웹사이트에 대한 액세스 속도를 높일 수 있는 무언가를 가능한 한 빨리 설치하고 시험해보고 싶어 했기 때문이다.[28]
2020~2021년에는 (최상위 웹 서버와 인기 있는 웹 브라우저에 의한) HTTP/2 구현에 관한 역학이 HTTP/3 프로토콜에 관한 향후 RFC의 고급 초안이 게시된 후 부분적으로 재현되었다.
기술 개요
[편집]
다음 기술 개요는 웹 서버에 구현될 수 있는 몇 가지 기능과 웹 서버가 수행할 수 있는 작업에 대한 아주 제한적인 예시를 제공하여 주제에 대한 충분히 폭넓은 시나리오를 갖추기 위한 시도로만 고려되어야 한다.
웹 서버 프로그램은 계획된 사용 목적에 유용하다고 간주되는 HTTPS 보안 변형 및 기타 기능과 확장을 종종 포함하여, 하나 이상의 HTTP 프로토콜 버전을 구현함으로써 클라이언트 서버 모델에서 서버의 역할을 수행한다.
웹 서버 프로그램의 복잡성과 효율성은 다음에 따라 크게 달라질 수 있다.[1]
- 구현된 공통 기능;
- 수행된 공통 작업;
- 목표로 하는 성능 및 확장성 수준;
- 원하는 성능 및 확장성 수준을 달성하기 위해 채택된 소프트웨어 모델 및 기법;
- 대상 하드웨어 및 사용 범주 (예: 임베디드 시스템, 저/중 트래픽 웹 서버, 고트래픽 인터넷 웹 서버).
공통 기능
[편집]웹 서버 프로그램은 구현 방식에 따라 다르지만, 대부분 공통적인 기능을 제공한다.
다음은 대부분의 웹 서버가 일반적으로 가지는 기본 기능이다.
- 정적 콘텐츠 제공: HTTP 프로토콜을 통해 클라이언트에 정적 콘텐츠(웹 파일)를 제공할 수 있다.
- HTTP: 클라이언트 HTTP 요청 버전과 호환되는 HTTP 응답 버전을 보내기 위해 하나 이상의 HTTP 프로토콜 버전을 지원 (예: HTTP/1.0, HTTP/1.1, HTTP/2, HTTP/3).
- 로깅: 일반적으로 웹 서버는 보안 및 통계 목적으로 클라이언트 요청 및 서버 응답에 대한 정보를 로그 파일에 기록하는 기능도 가지고 있다.
다른 더 고급이고 인기 있는 기능(아주 짧은 선택)은 다음과 같다.
- 동적 콘텐츠 제공: HTTP 프로토콜을 통해 클라이언트에 동적 콘텐츠(즉시 생성됨)를 제공할 수 있다.
- 가상 호스팅: 하나의 IP 주소만을 사용하여 여러 웹사이트(도메인 네임)를 제공할 수 있다.
- 승인: 웹사이트 경로(웹 리소스)의 일부에 대한 액세스를 허용하거나, 금지하거나, 승인할 수 있다.
- 콘텐츠 캐시: 서버 응답 속도를 높이기 위해 콘텐츠를 캐시할 수 있다.
- 대용량 파일 지원: 32비트 OS에서 크기가 2GB보다 큰 파일을 제공할 수 있다.
- 대역폭 제한: 네트워크가 포화되지 않도록 콘텐츠 응답 속도를 제한하여 더 많은 클라이언트를 지원할 수 있다.
- 다시쓰기 엔진: 간편 URL의 일부(클라이언트 요청에서 발견됨)를 실제 이름에 매핑할 수 있다.
- 사용자 정의 오류 페이지: 사용자 정의된 HTTP 오류 메시지를 지원한다.
공통 작업
[편집]웹 서버 프로그램은 실행될 때 일반적으로 여러 가지 일반적인 작업을 수행한다.[1]
- 시작하고, 선택적으로 구성 파일이나 다른 곳에 있는 설정을 읽고 적용하며, 선택적으로 로그 파일을 열고, 클라이언트 연결과 요청을 수신 대기하기 시작한다.
- 선택적으로 설정과 현재 운영 조건에 따라 일반적인 동작을 조정하려고 시도한다.
- 클라이언트 연결을 관리한다(필요에 따라 새로운 연결을 수락하거나 기존 연결을 닫음).
- 수신 클라이언트 요청(HTTP 메시지 읽기):
- 실행 또는 요청된 HTTP 메서드 거부:
- 선택적으로 URL 승인을 관리한다.
- 선택적으로 URL 리다이렉션을 관리한다.
- 선택적으로 정적 리소스(파일 콘텐츠)에 대한 요청을 관리한다:
- 선택적으로 디렉토리 인덱스 파일을 관리한다.
- 선택적으로 일반 파일을 관리한다.
- 선택적으로 동적 리소스에 대한 요청을 관리한다:
- 선택적으로 디렉토리 목록을 관리한다.
- 선택적으로 프로그램 또는 모듈 처리를 관리하며, 동적 콘텐츠 생성에 사용되는 외부 프로그램의 가용성, 시작 및 최종적으로 실행 중지를 확인한다.
- 선택적으로 동적 콘텐츠 생성에 사용되는 외부 프로그램 또는 내부 모듈과의 통신을 관리한다.
- 회신 클라이언트 요청에 대한 적절한 HTTP 응답(예: 요청된 리소스 또는 오류 메시지)을 전송하며, 최종적으로 동적 프로그램 및 모듈에서 보낸 HTTP 헤더를 확인하거나 추가한다.
- 선택적으로 외부 사용자 로그 파일이나 시스로그를 통해 시스템 로그 파일에 (부분적으로 또는 전체적으로) 클라이언트 요청 또는 응답을 기록하며, 일반적으로 공통 로그 형식을 사용한다.
- 선택적으로 시스로그나 기타 시스템 기능을 사용하여 감지된 이상 징후 또는 기타 주목할 만한 이벤트(예: 클라이언트 요청 또는 내부 작동)에 대한 프로세스 메시지를 기록하며, 이러한 로그 메시지는 일반적으로 디버그, 경고, 오류, 알림 수준을 가지며 설정에 따라 필터링(기록되지 않음)될 수 있다(심각도 수준 참조).
- 선택적으로 관리된 웹 트래픽이나 성능에 대한 통계를 생성한다.
- 기타 사용자 지정 작업.
요청 메시지 읽기
[편집]웹 서버 프로그램은 다음과 같이 할 수 있다:[29] [30] [31]
- HTTP 요청 메시지를 읽는다.
- 이를 해석한다.
- 구문을 검증한다.
- 알려진 HTTP 헤더를 식별하고 그로부터 값을 추출한다.
HTTP 요청 메시지가 디코딩되고 검증되면, 그 값들을 사용하여 해당 요청을 충족시킬 수 있는지 여부를 결정할 수 있다. 이를 위해서는 보안 검사를 포함한 많은 다른 단계가 필요하다.
URL 정규화
[편집]웹 서버 프로그램은 일반적으로 다음과 같은 이유로 URL 정규화를 수행한다(대부분의 HTTP 요청 메시지에서 발견되는 URL):
- 리소스 경로를 항상 웹사이트의 루트 디렉토리로부터의 깨끗한 균일 경로로 만든다.
- 보안 위험을 낮춘다(예: 웹사이트 루트 디렉토리 밖의 정적 리소스에 액세스하거나 금지되었거나 승인이 필요한 웹사이트 루트 디렉토리 아래의 경로 일부에 액세스하려는 시도를 더 쉽게 차단함으로써).
- 웹 리소스의 경로를 인간과 웹 로그 분석 프로그램(로그 분석기 또는 통계 애플리케이션이라고도 함)이 더 쉽게 인식할 수 있도록 만든다.
URL 정규화라는 용어는 URL을 일관된 방식으로 수정하고 표준화하는 과정을 의미한다. 스키마와 호스트를 소문자로 변환하는 것을 포함하여 수행될 수 있는 몇 가지 유형의 정규화가 있다. 가장 중요한 정규화 중 하나는 "." 및 ".." 경로 세그먼트를 제거하고 비어 있지 않은 경로 구성 요소에 후행 슬래시를 추가하는 것이다.
URL 매핑
[편집]"URL 매핑은 웹 서버나 애플리케이션 프레임워크가 들어오는 URL 요청이 적절한 리소스, 핸들러 또는 작업으로 어떻게 라우팅되는지 결정하는 과정이다. 현대의 URL 매핑 메커니즘은 요청된 URL의 구조를 분석하고 라우팅 규칙이나 구성 패턴을 사용하여 파일 시스템 경로에 직접 의존하지 않고 정적 리소스를 제공하거나, 동적 핸들러를 호출하거나, 다시쓰기 및 리다이렉션을 수행한다. 이러한 접근 방식은 깨끗하고 인간이 읽을 수 있는 URL과 유연한 애플리케이션 아키텍처를 가능하게 한다.[32]
실제로 단순 정적 콘텐츠 제공(예: 다시쓰기 엔진, 동적 콘텐츠 제공)을 넘어선 고급 기능을 구현하는 웹 서버 프로그램은 일반적으로 해당 URL을 다음과 같이 처리하는 방법을 파악해야 한다:
웹 서버의 하나 이상의 구성 파일은 URL 경로의 일부(예: 파일 경로의 초기 부분, 파일 확장자 및 기타 경로 구성 요소)를 특정 URL 핸들러(파일, 디렉토리, 외부 프로그램 또는 내부 모듈)로 매핑하는 것을 지정할 수 있다.[33]
웹 서버가 위에서 언급한 고급 기능 중 하나 이상을 구현하면, 유효한 URL의 경로 부분은 항상 웹사이트 디렉토리 트리 아래의 기존 파일 시스템 경로(파일 시스템의 파일 또는 디렉토리)와 일치하지 않을 수 있다. 왜냐하면 그것은 동적 요청을 위한 내부 또는 외부 모듈 프로세서의 가상 이름을 참조할 수 있기 때문이다.
파일 시스템으로의 URL 경로 변환
[편집]웹 서버 프로그램은 물리적 파일 시스템 경로를 참조하는 URL 경로(전체 또는 일부)를 대상 웹사이트의 루트 디렉토리 아래의 절대 경로로 변환할 수 있다.[33]
웹사이트의 루트 디렉토리는 구성 파일에 의해 지정되거나, HTTP 클라이언트 요청에서 발견된 URL의 호스트 부분인 웹사이트 이름을 사용하여 웹 서버의 내부 규칙에 의해 지정될 수 있다.[33]
파일 시스템으로의 경로 변환은 다음과 같은 유형의 웹 리소스에 대해 수행된다:
- 로컬, 일반적으로 실행 불가능한 파일(파일 콘텐츠에 대한 정적 요청).
- 로컬 디렉토리(동적 요청: 즉시 생성되는 디렉토리 목록).
- 프로그램 이름(CGI 또는 SCGI 인터페이스를 사용하여 실행되고 그 출력이 웹 서버에 의해 읽히고 HTTP 요청을 한 클라이언트로 다시 전송되는 동적 요청).
웹 서버는 요청된 URL(HTTP 요청 메시지)에서 찾은 경로를 웹사이트 루트 디렉토리 경로에 추가한다. 아파치 서버에서는 이것이 일반적으로 /home/www/website이다(유닉스 기계에서는 일반적으로 /var/www/website임). 이것이 어떻게 결과가 나올 수 있는지에 대한 다음 예시를 참조하라.
정적 파일 요청을 위한 URL 경로 변환
다음 URL로 지정된 기존 파일의 정적 요청 예시:
http://www.example.com/path/file.html
클라이언트의 사용자 에이전트는 www.example.com에 연결한 다음 다음 HTTP/1.1 요청을 보낸다:
GET /path/file.html HTTP/1.1 Host: www.example.com Connection: keep-alive
결과는 로컬 파일 시스템 리소스이다:
/home/www/www.example.com/path/file.html
그 다음 웹 서버는 파일이 존재하면 이를 읽고 클라이언트의 웹 브라우저에 응답을 보낸다. 응답은 파일의 콘텐츠를 설명하고 파일 자체를 포함하거나, 파일이 존재하지 않거나 액세스가 금지되었다는 오류 메시지가 반환된다.
디렉토리 요청을 위한 URL 경로 변환 (정적 인덱스 파일 없음)
다음 URL로 지정된 기존 디렉토리의 암시적 동적 요청 예시:
http://www.example.com/directory1/directory2/
클라이언트의 사용자 에이전트는 www.example.com에 연결한 다음 다음 HTTP/1.1 요청을 보낸다:
GET /directory1/directory2 HTTP/1.1 Host: www.example.com Connection: keep-alive
결과는 로컬 디렉토리 경로이다:
/home/www/www.example.com/directory1/directory2/
그 다음 웹 서버는 디렉토리의 존재 여부를 확인하고, 존재하고 액세스할 수 있는 경우 인덱스 파일(이 경우 존재하지 않음)을 찾으려고 시도한 다음, 디렉토리 목록 전용 내부 모듈이나 프로그램에 요청을 전달하고 최종적으로 데이터 출력을 읽고 클라이언트의 웹 브라우저에 응답을 보낸다. 응답은 디렉토리의 콘텐츠(포함된 하위 디렉토리 및 파일 목록)를 설명하거나, 디렉토리가 존재하지 않거나 액세스가 금지되었다는 오류 메시지가 반환된다.
동적 프로그램 요청을 위한 URL 경로 변환
동적 요청의 경우, 클라이언트가 지정한 URL 경로는 웹 서버가 동적 콘텐츠를 생성하는 데 사용하는 기존 외부 프로그램(일반적으로 CGI가 포함된 실행 파일)을 참조해야 한다.[34]
프로그램 파일을 사용하여 출력을 생성하는 동적 요청 예시:
http://www.example.com/cgi-bin/forum.php?action=view&orderby=thread&date=2021-10-15
클라이언트의 사용자 에이전트는 www.example.com에 연결한 다음 다음 HTTP/1.1 요청을 보낸다:
GET /cgi-bin/forum.php?action=view&ordeby=thread&date=2021-10-15 HTTP/1.1 Host: www.example.com Connection: keep-alive
결과는 프로그램의 로컬 파일 경로이다(이 예시에서는 PHP 프로그램):
/home/www/www.example.com/cgi-bin/forum.php
웹 서버는 경로 정보와 쿼리 문자열 action=view&orderby=thread&date=2021-10-15를 전달하여 프로그램을 실행하므로 프로그램은 실행하는 데 필요한 정보를 가진다. (이 경우 2021년 10월 15일부터 스레드별로 정렬된 포럼 항목 보기가 포함된 HTML 문서를 반환한다). 이에 더해, 웹 서버는 외부 프로그램에서 보낸 데이터를 읽고 요청을 한 클라이언트에 해당 데이터를 다시 전송한다.
요청 메시지 관리
[편집]요청이 읽히고, 해석되고, 검증되면, 메서드, URL 및 파라미터(HTTP 헤더 값을 포함할 수 있음)에 따라 관리되어야 한다.
실제로 웹 서버는 다음 응답 경로 중 하나를 사용하여 요청을 처리해야 한다:[33]
- 요청 내용에 허용할 수 없는 것이 있으면(상태 라인 또는 메시지 헤더), 웹 서버는 이미 오류 응답을 보냈다.
- 요청에 웹 서버의 일반 코드로 충족될 수 있는 메서드(예:
OPTIONS)가 있으면 성공적인 응답이 전송된다. - URL에 승인이 필요한 경우 승인 오류 메시지가 전송된다.
- URL이 리다이렉션에 매핑되면 리다이렉트 메시지가 전송된다.
- URL이 동적 리소스(가상 경로 또는 디렉토리 목록)에 매핑되면 해당 핸들러(내부 모듈 또는 외부 프로그램)가 호출되고 요청 파라미터(쿼리 문자열 및 경로 정보)가 해당 요청에 회신할 수 있도록 전달된다.
- URL이 정적 리소스(일반적으로 파일 시스템의 파일)에 매핑되면 내부 정적 핸들러가 호출되어 해당 파일을 전송한다.
- 요청 메서드를 알 수 없거나 기타 허용할 수 없는 조건(예: 리소스를 찾을 수 없음, 내부 서버 오류 등)이 있으면 오류 응답이 전송된다.
정적 콘텐츠 제공
[편집]
웹 서버 프로그램이 정적 콘텐츠 제공이 가능하고 그렇게 하도록 설정된 경우, 요청 메시지의 유효한 URL 경로가 (URL 매핑, URL 변환 및 URL 리다이렉션 후) 웹사이트 루트 디렉토리 아래의 기존 파일과 일치하고 파일 속성이 웹 서버 프로그램의 내부 규칙과 일치할 때마다 파일 콘텐츠를 전송할 수 있다.[33]
그런 종류의 콘텐츠는 클라이언트에 전송될 때 일반적으로 웹 서버에 의해 변경되지 않고 (파일 수정) 어떤 프로그램에 의해 수정될 때까지 동일하게 유지되기 때문에 정적이라고 불린다.
참고: 정적 콘텐츠만 제공할 때, 웹 서버 프로그램은 일반적으로 제공되는 웹사이트의 파일 콘텐츠를 변경하지 않으며(읽기만 하고 쓰기는 절대 안 함), 따라서 다음 HTTP 메서드만 지원하면 충분하다:
OPTIONSHEADGET
정적 파일 콘텐츠의 응답은 파일 캐시에 의해 속도가 향상될 수 있다.
디렉토리 인덱스 파일
[편집]웹 서버 프로그램이 경로가 기존 디렉토리와 일치하는 URL이 있는 클라이언트 요청 메시지를 수신하고 해당 디렉토리에 액세스할 수 있으며 디렉토리 인덱스 파일 제공이 활성화된 경우, 웹 서버 프로그램은 해당 디렉토리에서 알려진(또는 설정된) 정적 인덱스 파일 이름(일반 파일) 중 첫 번째를 제공하려고 시도할 수 있다. 인덱스 파일이 없거나 기타 조건이 충족되지 않으면 오류 메시지가 반환된다.
정적 인덱스 파일로 가장 많이 사용되는 이름은 index.html, index.htm 및 Default.htm이다.
일반 파일
[편집]웹 서버 프로그램이 경로가 기존 파일의 파일 이름과 일치하는 URL이 있는 클라이언트 요청 메시지를 수신하고 해당 파일에 웹 서버 프로그램이 액세스할 수 있으며 파일 속성이 웹 서버 프로그램의 내부 규칙과 일치하는 경우, 웹 서버 프로그램은 해당 파일을 클라이언트에 보낼 수 있다.
일반적으로 보안상의 이유로 대부분의 웹 서버 프로그램은 일반 파일만 제공하거나 장치 파일과 같은 특수 파일 유형, 그리고 이에 대한 심볼릭 링크 또는 하드 링크를 사용하지 않도록 미리 구성된다. 그 목적은 정적 웹 리소스를 제공할 때 바람직하지 않은 부작용을 피하는 것이다.[35]
동적 콘텐츠 제공
[편집]
웹 서버 프로그램이 동적 콘텐츠 제공이 가능하고 그렇게 하도록 설정된 경우, 요청된 URL 경로와 연결된 적절한 내부 모듈이나 외부 프로그램과 통신하여 클라이언트 요청의 파라미터를 전달할 수 있다. 그 후, 웹 서버 프로그램은 (종종 즉석에서 생성된) 데이터 응답을 읽은 다음 요청을 한 클라이언트 프로그램에 다시 전송한다.[36]
참고: 정적 및 동적 콘텐츠를 제공할 때, 웹 서버 프로그램은 일반적으로 클라이언트로부터 데이터를 안전하게 수신할 수 있어야 하며, 따라서 대용량 데이터 세트(예: 많은 데이터 입력 또는 파일 업로드)를 웹 서버, 외부 프로그램 또는 모듈로 보낼 수 있는 대화형 폼이 있는 웹사이트도 호스팅할 수 있어야 하므로 다음 HTTP 메서드도 지원해야 한다:
POST
내부 모듈이나 외부 프로그램과 통신하기 위해서는 웹 서버 프로그램이 사용 가능한 많은 게이트웨이 인터페이스 중 하나 이상을 구현해야 한다(동적 콘텐츠에 사용되는 웹 서버 게이트웨이 인터페이스 참조).
세 가지 표준 및 역사적인 게이트웨이 인터페이스는 다음과 같다.
- CGI
- 외부 CGI 프로그램은 각 동적 요청에 대해 웹 서버 프로그램에 의해 실행되며, 웹 서버 프로그램은 생성된 데이터 응답을 읽은 다음 클라이언트에 다시 전송한다.
- SCGI
- 외부 SCGI 프로그램(일반적으로 프로세스)은 웹 서버 프로그램이나 다른 프로그램 또는 프로세스에 의해 한 번 시작된 다음 네트워크 연결을 기다린다. 해당 프로그램에 대한 새로운 요청이 있을 때마다 웹 서버 프로그램은 요청 파라미터를 보내고 데이터 응답을 읽기 위해 새로운 네트워크 연결을 만들고, 연결이 닫힌다.
- FastCGI
- 외부 FastCGI 프로그램(일반적으로 프로세스)은 웹 서버 프로그램이나 다른 프로그램 또는 프로세스에 의해 한 번 시작된 다음 웹 서버에 의해 영구적으로 설정된 네트워크 연결을 기다린다. 해당 연결을 통해 요청 파라미터가 전송되고 데이터 응답이 읽힌다.
디렉토리 목록
[편집]
웹 서버 프로그램은 파일 및 하위 디렉토리의 디렉토리 인덱스 목록을 (즉석에서) 동적으로 생성할 수 있다.[37]
웹 서버 프로그램이 그렇게 하도록 설정되어 있고 요청된 URL 경로가 기존 디렉토리와 일치하며 액세스가 허용되고 해당 디렉토리 아래에서 정적 인덱스 파일을 찾을 수 없는 경우, 언급된 디렉토리의 파일 또는 하위 디렉토리 목록을 포함하는 웹 페이지(일반적으로 HTML 형식)가 동적으로(즉석에서) 생성된다. 생성할 수 없는 경우 오류가 반환된다.
일부 웹 서버 프로그램은 디렉토리 목록 사용자 지정을 허용한다. 플레이스홀더(예: $(FILE_NAME), $(FILE_SIZE) 등)를 포함하는 HTML 문서인 웹 페이지 템플릿(예: index.tpl)을 사용하거나, 해석 및 실행되는 HTML과 포함된 소스 코드를 사용(예: index.asp)하거나, CGI, SCGI, FCGI(예: index.cgi, index.php, index.fcgi)와 같은 동적 인덱스 프로그램 사용을 지원함으로써 가능하다.
동적으로 생성된 디렉토리 목록의 사용은 생성 과정이 정적 인덱스 페이지를 보내는 것보다 훨씬 더 많은 OS 리소스를 차지하기 때문에 일반적으로 웹사이트의 몇몇 선택된 디렉토리로 제한되거나 피한다.
디렉토리 목록의 주요 용도는 (이름, 크기, 수정 날짜-시간 또는 파일 특성이 무작위로 자주 변경될 수 있는 경우) 파일을 있는 그대로 다운로드할 수 있도록 하는 것이며, 요청하는 사용자에게 추가 정보를 제공할 필요가 없다.[38]
프로그램 또는 모듈 처리
[편집]외부 프로그램 또는 내부 모듈(처리 장치)은 하나 이상의 데이터 저장소로부터 데이터를 가져오거나 저장하는 데 사용될 수 있는 일종의 애플리케이션 기능을 실행할 수 있다:
- 파일 (파일 시스템);
- 데이터베이스 (DB);
- 로컬 컴퓨터나 다른 컴퓨터에 위치한 다른 소스.
처리 장치는 데이터 저장소에서 검색된 데이터를 사용하여 다음을 포함한 모든 종류의 웹 콘텐츠를 반환할 수 있다:
- 문서 (예: HTML, XML 등);
- 이미지;
- 비디오;
- 구조화된 데이터 (예: 웹 인터페이스의 동적 페이지(DHTML)에 의해 표시되는 하나 이상의 값을 업데이트하는 데 사용될 수 있으며 XMLHttpRequest API에 의해 요청되었을 수 있는 데이터) (참조: 동적 페이지).
실제로 클라이언트 요청이나 구성 설정에 포함된 하나 이상의 파라미터에 따라 변경될 수 있는 콘텐츠가 있을 때마다 일반적으로 동적으로 생성된다.
응답 메시지 전송
[편집]웹 서버 프로그램은 클라이언트 요청 메시지에 대한 회신으로 응답 메시지를 보낼 수 있다.[29]
요청 메시지를 성공적으로 읽거나, 디코딩하거나, 분석하거나, 실행할 수 없었기 때문에 오류 응답 메시지가 전송될 수 있다.[30]
참고: 다음 섹션은 웹 서버가 다소 무엇을 하는지 이해하는 데 도움이 되는 예시로만 보고되었으며, 이 섹션은 결코 완전하거나 exhaustive하지 않다.
오류 메시지
[편집]웹 서버 프로그램은 여러 종류의 오류 메시지로 클라이언트 요청 메시지에 회신할 수 있으며, 어쨌든 이러한 오류는 주로 두 가지 범주로 나뉜다:
- HTTP 클라이언트 오류: 요청 메시지 유형이나 요청된 웹 리소스의 가용성으로 인해 발생.[39]
- HTTP 서버 오류: 내부 서버 오류로 인해 발생.[40]
오류 응답이나 메시지가 클라이언트 브라우저에 의해 수신되면, 메인 사용자 요청(예: 웹 페이지와 같은 웹 리소스의 URL)과 관련이 있는 경우 일반적으로 해당 오류 메시지가 브라우저 창이나 메시지에 표시된다.
URL 승인
[편집]웹 서버 프로그램은 요청된 URL 경로가 다음을 수행할 수 있는지 확인할 수 있다:[41]
승인 또는 액세스 권한 기능이 구현되고 활성화되었으며 웹 리소스에 대한 액세스가 허용되지 않는 경우, 필요한 액세스 권한에 따라 웹 서버 프로그램은:
URL 리다이렉션
[편집]웹 서버 프로그램은 URL 리다이렉션을 수행하여 새로운 URL(새로운 위치)로 리다이렉션하는 기능이 있을 수 있으며, 이는 유효하거나 기존의 웹 리소스에 액세스하기에 적합한 새로운 URL이 포함된 응답 메시지로 클라이언트 요청 메시지에 회신하는 것으로 구성된다(클라이언트는 새로운 URL로 요청을 다시 수행해야 한다).[42]
위치 URL 리다이렉션은 다음과 같이 사용된다:[42]
- 마지막 슬래시 '/'를 추가하여 디렉토리 이름을 수정한다.[37]
- 더 이상 존재하지 않는 URL 경로에 대해 해당 웹 리소스를 찾을 수 있는 새 경로에 대한 새로운 URL을 제공한다.
- 현재 도메인에 부하가 너무 많을 때 다른 도메인에 대한 새로운 URL을 제공한다.
예시 1: URL 경로가 디렉토리 이름을 가리키지만 마지막 슬래시 '/'가 없으므로 웹 서버는 클라이언트에 리다이렉트를 보내 수정된 경로 이름으로 요청을 다시 수행하도록 지시한다.[37]
시작:
/directory1/directory2
대상:
/directory1/directory2/
예시 2: 파일 시스템 경로를 재구성하기 위해 일련의 문서 전체가 웹사이트 내부에서 이동되었다.
시작:
/directory1/directory2/2021-10-08/
대상:
/directory1/directory2/2021/10/08/
예시 3: 일련의 문서 전체가 새 웹사이트로 이동되었으며 이제 액세스하려면 보안 HTTPS 연결을 사용하는 것이 의무적이다.
시작:
http://www.example.com/directory1/directory2/2021-10-08/
대상:
https://docs.example.com/directory1/2021-10-08/
위의 예시는 가능한 여러 종류의 리다이렉션 중 일부일 뿐이다.
성공 메시지
[편집]웹 서버 프로그램은 요청된 웹 리소스 데이터를 선택적으로 포함하는 성공 메시지로 유효한 클라이언트 요청 메시지에 회신할 수 있다.[43]
웹 리소스 데이터가 클라이언트로 다시 전송되는 경우, 검색된 방식(파일에서 검색되었는지 또는 프로그램이나 모듈의 출력에서 검색되었는지)에 따라 정적 콘텐츠일 수도 있고 동적 콘텐츠일 수도 있다.
콘텐츠 캐시
[편집]평균 HTTP 응답 시간을 낮추고 하드웨어 리소스 사용량을 줄여 웹 서버 응답 속도를 높이기 위해, 많은 인기 있는 웹 서버는 콘텐츠 범주마다 전문화된 하나 이상의 콘텐츠 캐시를 구현한다.[44] [45]
콘텐츠는 일반적으로 출처별로 캐시된다:
파일 캐시
[편집]역사적으로 1960년대 중반~후반 및 1970년대부터 자주, 무작위로, 빠르게 액세스해야 했던 파일에 있는 정적 콘텐츠는 주로 전기 기계식 디스크에 저장되었다. 안타깝게도 해당 종류의 장치에 대한 읽기 및 쓰기는 RAM 속도와 비교할 때 매우 느린 작업으로 간주되어 왔으며, 따라서 초기 운영체제부터 먼저 디스크 캐시가 개발되었고, 그 다음에는 자주 액세스되는 데이터의 I/O 작업 속도를 높이기 위해 운영체제 파일 캐시 하위 시스템이 개발되었다.
운영체제 파일 캐시의 도움을 받더라도, 디스크에 저장된 디렉토리 및 파일과 관련된 I/O 작업의 상대적 또는 가끔 발생하는 느림은 웹 인터넷 트래픽이 인터넷이나 네트워크 라인의 속도가 지속적으로 증가함에 따라 기하급수적으로 성장하기 시작한 1990년대 중반~후반부터 특히 최상위 웹 서버에서 기대되는 성능 증가의 병목 현상이 되기 시작했다.
정적 파일 제공 속도를 더 효율적으로 높여 초당 최대 요청 수 또는 응답 수(RPS)를 늘리는 방법에 대한 문제는 웹 서버 프로그램에 구현될 수 있는 유용한 캐시 모델을 제안하기 위해 1990년대 중반부터 연구되기 시작했다.[46]
실제로 오늘날 많은 웹 서버 프로그램은 웹 서버 사용에 맞춰 조정되고 특정 구현 및 파라미터를 사용하는 자체 사용자 공간 파일 캐시를 포함한다.[47] [48] [49]
RAID 및 빠른 솔리드 스테이트 드라이브(매우 높은 I/O 속도를 가진 스토리지 하드웨어)의 광범위한 채택은 웹 서버에 통합된 파일 캐시를 가지는 이점을 약간 줄였지만 물론 제거하지는 않았다.
동적 캐시
[편집]내부 모듈이나 외부 프로그램에 의해 출력된 동적 콘텐츠는 (키나 파라미터가 있는 고유한 URL이 주어질 때) 항상 매우 자주 변경되지는 않을 수 있으므로, 잠시 동안(예: 1초에서 몇 시간 이상) 결과 출력을 RAM이나 빠른 디스크에 캐시할 수 있다.[50]
동적 캐시의 일반적인 용도는 뉴스, 날씨, 이미지, 지도 등에 대한 동적 웹페이지를 가진 웹사이트인데, 이는 자주(예: n분마다) 변경되지 않으며 분당, 시간당 엄청난 수의 클라이언트가 액세스하는 경우이다. 그러한 경우 클라이언트가 종종 브라우저 캐시에 요청된 콘텐츠의 업데이트된 복사본을 가지고 있지 않기 때문에 캐시된 콘텐츠를 반환하는 것이 유용하다(내부 모듈이나 외부 프로그램을 호출하지 않고).[51]
어쨌든 대부분의 경우 그러한 종류의 캐시는 웹 서버와 하드웨어 리소스(CPU, RAM, 디스크)를 놓고 경쟁하지 않기 위해 외부 서버(예: 리버스 프록시)에 의해 구현되거나 특정 애플리케이션(예: Memcached)에 의해 관리되는 별도의 컴퓨터에 동적 데이터 출력을 저장함으로써 구현된다.[52] [53]
커널 모드 및 사용자 모드 웹 서버
[편집]웹 서버 소프트웨어는 운영체제에 통합되어 커널 공간에서 실행되거나, (다른 일반 애플리케이션처럼) 사용자 공간에서 실행될 수 있다.
커널 모드에서 실행되는 웹 서버(일반적으로 커널 공간 웹 서버라고 함)는 커널 리소스에 직접 액세스할 수 있어 이론상 사용자 모드에서 실행되는 서버보다 빠를 수 있지만, 커널 모드에서 웹 서버를 실행하는 데는 단점이 있다(예: 소프트웨어 개발 및 디버깅의 어려움). 한편 런타임 치명적 오류는 OS 커널에 심각한 문제를 일으킬 수 있다.
사용자 모드에서 실행되는 웹 서버는 더 많은 메모리나 더 많은 CPU 리소스를 사용하는 것에 대해 시스템에 허가를 요청해야 한다. 커널에 대한 이러한 요청은 시간이 걸릴 뿐만 아니라 시스템이 자체 용도를 위해 리소스를 예약하고 다른 모든 실행 중인 애플리케이션과 하드웨어 리소스를 공유할 책임이 있기 때문에 항상 충족되지 않을 수 있다. 사용자 모드에서 실행하는 것은 (사용자 공간과 커널 공간 사이의) 더 많은 버퍼나 데이터 복사를 의미할 수도 있으며, 이는 사용자 모드 웹 서버의 성능 저하로 이어질 수 있다.
오늘날 거의 모든 웹 서버 소프트웨어는 사용자 모드에서 실행된다(전술한 작은 단점들의 대부분이 더 빠른 하드웨어, 새로운 OS 버전, 훨씬 더 빠른 OS 시스템 호출, 새로운 최적화된 웹 서버 소프트웨어에 의해 극복되었기 때문이다). 어떤 서버가 커널 모드에서 실행되고 어떤 서버가 사용자 모드에서 실행되는지(커널 공간 또는 사용자 공간이라고도 함) 알아보려면 웹 서버 소프트웨어 비교를 참조하라.
성능
[편집]사용자 경험을 (클라이언트 또는 브라우저 측에서) 개선하기 위해, 웹 서버는 클라이언트 요청에 빠르게 회신해야 한다(가능한 한 빨리). (구성에 따라) 특정 유형의 파일(예: 대용량 파일)에 대해 콘텐츠 응답이 제한(throttled)되지 않는 한, 반환된 데이터 콘텐츠도 네트워크로 가능한 한 빨리 전송되어야 한다(높은 전송 속도).
다시 말해, 웹 서버는 항상 매우 응답이 빨라야 하며, 높은 웹 트래픽 부하 하에서도 사용자의 총 대기 시간(브라우저 시간 + 네트워크 시간 + 웹 서버 응답 시간)이 가능한 한 낮게 유지되도록 해야 한다.
성능 지표
[편집]웹 서버 소프트웨어의 경우, (다양한 운영 조건 하에서 측정되는) 주요 성능 지표는 일반적으로 적어도 다음과 같다:[54]
- 초당 요청 수 (RPS, HTTP 버전 및 구성, HTTP 요청 유형 및 기타 운영 조건에 따라 QPS와 유사);
- 초당 연결 수 (CPS), 웹 서버가 수락하는 초당 연결 수 (HTTP/1.0 또는 연결당 요청이나 응답 제한이 매우 낮은(즉, 1..20개) HTTP/1.1을 사용할 때 유용);
- 네트워크 지연 시간 + 응답 시간 (각 새 클라이언트 요청에 대해). 일반적으로 벤치마크 도구는 얼마나 많은 요청이 시간 경과 척도(예: 1ms, 3ms, 5ms, 10ms, 20ms, 30ms, 40ms 이내) 내에 충족되었는지 또는 가장 짧은, 평균, 가장 긴 응답 시간을 보여준다;
- 응답의 처리량 (초당 바이트 수).
운영 조건 중에서 테스트 중에 사용되는 동시 클라이언트 연결의 수(1..n)는 웹 서버가 지원하는 병행성 수준을 테스트된 성능 지표의 결과와 연관시킬 수 있게 해주기 때문에 중요한 파라미터이다.
소프트웨어 효율성
[편집]채택된 특정 웹 서버 소프트웨어 설계 및 모델:
... 및 기타 프로그래밍 기법(예:):
- 가능한 CPU 캐시 미스 최소화;
- 속도를 위해 임계 경로에서의 가능한 CPU 분기 예측 미스 최소화;
- 특정 함수나 작업을 수행하는 데 사용되는 시스템 호출 횟수 최소화;
- 기타 트릭;
... 웹 서버 프로그램을 구현하는 데 사용되어 성능을 크게 좌우할 수 있으며, 특히 무거운 부하 하에서 또는 고사양 하드웨어(많은 CPU, 디스크 및 많은 RAM)를 사용할 때 달성할 수 있는 확장성 수준을 크게 좌우할 수 있다.
실제로 일부 웹 서버 소프트웨어 모델은 잘 작동하여 목표 성능을 달성하기 위해 다른 모델보다 더 많은 OS 리소스(특히 더 많은 CPU와 더 많은 RAM)를 요구할 수 있다.
운영 조건
[편집]웹 서버의 성능에 영향을 줄 수 있는 많은 운영 조건이 있다. 성능 값은 다음에 따라 달라질 수 있다:
- 웹 서버 설정(로그 파일 활성화 여부 등을 포함).
- 클라이언트 요청에서 사용된 HTTP 버전.
- 평균 HTTP 요청 유형(메서드, HTTP 헤더의 길이 및 선택적 바디).
- 요청된 콘텐츠가 정적인지 동적인지 여부.
- 콘텐츠가 (서버 또는 클라이언트에 의해) 캐시되었는지 여부.
- 콘텐츠가 즉석에서 압축되는지(전송 시), 사전 압축되는지(즉, 파일 리소스가 이미 압축된 상태로 디스크에 저장되어 있어 웹 서버가 콘텐츠가 압축되었다는 표시만으로 파일을 네트워크로 직접 보낼 수 있는 경우) 또는 전혀 압축되지 않는지 여부.
- 연결이 암호화되었는지 여부.
- 웹 서버와 클라이언트 간의 평균 네트워크 속도.
- 활성 TCP 연결 수.
- 웹 서버가 관리하는 활성 프로세스 수(외부 CGI, SCGI, FCGI 프로그램 포함).
- 웹 서버가 실행되는 컴퓨터의 OS의 하드웨어 및 소프트웨어 제한 또는 설정.
- 기타 사소한 조건들.
벤치마킹
[편집]웹 서버의 성능은 일반적으로 사용 가능한 자동 부하 테스트 도구를 사용하여 벤치마킹된다.
부하 제한
[편집]웹 서버(프로그램 설치)는 일반적으로 운영 조건의 각 조합에 대해 미리 정의된 부하 제한을 가진다. 이는 또한 OS 리소스에 의해 제한되고 각 활성 웹 서버 프로세스당 제한된 수의 동시 클라이언트 연결(일반적으로 2개에서 수만 개 사이)만 처리할 수 있기 때문이다(C10k 문제 및 C10M 문제 참조).
웹 서버가 부하 제한에 근접하거나 초과하면 과부하 상태가 되고, 따라서 응답하지 않을 수 있다.
과부하 원인
[편집]언제든지 웹 서버는 다음과 같은 하나 이상의 원인으로 인해 과부하가 걸릴 수 있다:
- 합법적인 웹 트래픽 초과. 짧은 시간 안에 수천 또는 수백만 명의 클라이언트가 웹사이트에 연결하는 경우(예: 슬래시닷 효과).
- 분산 서비스 거부 공격. 서비스 거부 공격(DoS 공격) 또는 분산 서비스 거부 공격(DDoS 공격)은 컴퓨터나 네트워크 리소스를 의도한 사용자가 사용할 수 없도록 만들려는 시도이다.
- 때때로 (조정되지 않은) 수백만 대의 감염된 컴퓨터로 인해 비정상적인 트래픽을 유발하는 웜 (웜).
- XSS 웜은 수백만 대의 감염된 브라우저나 웹 서버로 인해 높은 트래픽을 유발할 수 있다.
- 매우 적은 네트워크 리소스(예: 대역폭)나 하드웨어 리소스(CPU, RAM, 디스크)를 가진 대규모 웹사이트에서 필터링하거나 제한하지 않은 인터넷 봇 트래픽.
- 인터넷(네트워크) 속도 저하(예: 패킷 손실로 인해). 클라이언트 요청이 더 느리게 제공되어 연결 수가 너무 많이 증가하여 서버 제한에 도달하게 된다.
- 동적 콘텐츠를 제공하는 웹 서버가 백엔드 컴퓨터(예: 데이터베이스)로부터 오는 느린 응답을 기다리는 경우. 데이터베이스 데이터의 너무 많은 삽입이나 업데이트가 쿼리와 혼합되어 너무 많이 발생하기 때문일 수 있다. 이러한 경우 웹 서버는 HTTP 클라이언트에 회신하기 전에 백엔드 데이터 응답을 기다려야 하지만, 이 기다리는 동안 너무 많은 새 클라이언트 연결이나 요청이 도착하여 과부하 상태가 된다.
- 웹 서버(컴퓨터)의 부분적 가용성. 이는 필수적이거나 긴급한 유지 보수 또는 업그레이드, 하드웨어 또는 소프트웨어 오류(예: 백엔드(예: 데이터베이스) 오류)로 인해 발생할 수 있다. 이러한 경우 나머지 웹 서버에 너무 많은 트래픽이 몰려 과부하가 걸릴 수 있다.
과부하 증상
[편집]과부하된 웹 서버의 증상은 일반적으로 다음과 같다:
과부하 방지 기법
[편집]위의 평균 부하 제한을 부분적으로 극복하고 과부하를 방지하기 위해, 대부분의 인기 있는 웹사이트는 다음과 같은 일반적인 기법을 사용한다:
- 하드웨어 기능 및 사용량에 맞게 OS 파라미터 튜닝.
- 보안 및 성능을 향상시키기 위해 웹 서버 파라미터 튜닝.
- 웹 캐시 기법 배포 (정적 콘텐츠뿐만 아니라, 가능한 경우 동적 콘텐츠도 포함).
- 네트워크 트래픽 관리, 다음 방법 사용:
- 정적 및 동적 콘텐츠의 다른 종류를 제공하기 위해 다른 도메인 네임, IP 주소 및 컴퓨터 사용. 그 목적은 대용량 파일(
download.*)(해당 도메인은 CDN으로 대체될 수도 있음)을 중소형 파일(static.*) 및 메인 동적 사이트(일부 콘텐츠가 백엔드 데이터베이스에 저장되는 곳)(www.*)에서 분리하는 것이다. 그 아이디어는 (다운로드 속도를 제한할 수도 있음) 크고 방대한(10–1000MB 이상) 파일을 효율적으로 제공하고 중소형 파일을 완전히 캐시하여, 각각의 웹 서버 컴퓨터 (그룹)에 대해 다른 설정을 사용하여 부하가 무거운 상황에서 동적 사이트의 성능에 영향을 주지 않는 것이다:https://download.example.comhttps://static.example.comhttps://www.example.com
- 로드 밸런서 뒤에 그룹화된 많은 웹 서버(컴퓨터)를 사용하여 하나의 큰 웹 서버로 작동하거나 보이도록 함.
- 각 컴퓨터에 더 많은 하드웨어 리소스(예: RAM, 빠른 디스크)를 추가.
- 웹 서버를 위해 더 효율적인 컴퓨터 프로그램 사용 (참조: 소프트웨어 효율성).
- 동적 요청을 처리하기 위해 가장 효율적인 웹 서버 게이트웨이 인터페이스 사용(동적 페이지가 검색될 때마다 하나 이상의 외부 프로그램을 생성하는 것은 성능을 죽인다).
- 동적 콘텐츠가 포함된 경우 특히 HTTP 응답 속도를 높이기 위해 다른 프로그래밍 기법과 워크어라운드 사용(예: 스타일 시트, 이미지 및 스크립트와 같은 객체를 검색하기 위해 동적 호출을 피함). 이는 절대 변경되지 않거나 매우 드물게 변경되는 콘텐츠를 정적 파일로 한 번 복사하고 동적 콘텐츠와 동기화된 상태로 유지함으로써 수행된다.
- HTTP의 최신 효율적인 버전 사용 (예: 일반적인 HTTP/1.1 사용 외에도 가용한 웹 서버 소프트웨어가 후자 두 프로토콜을 안정적으로 지원할 때마다 HTTP/2 및 아마도 HTTP/3까지 활성화). 이는 각 클라이언트가 시작하는 TCP/IP 연결 수와 (더 간결한 HTTP 헤더 표현과 아마도 데이터 압축으로 인해) 교환되는 데이터 크기를 크게 줄이기 위해서이다. 이것이 암호화 필요성으로 인한 RAM 및 CPU의 과부하를 방지하지는 못할 수 있다. 또한 동시성에 최적화되어 있기 때문에 고속으로 업로드되는 과도하게 큰 파일로 인한 과부하를 해결하지 못할 수도 있다.[59][60]
시장 점유율
[편집]
가장 인기 있는 웹 서버의 모든 사이트에 대한 시장 점유율 2005–2021

가장 인기 있는 웹 서버의 모든 사이트에 대한 시장 점유율 1995–2005
다음은 Netcraft가 발표한 인터넷상 주요 웹 서버들의 모든 사이트에 대한 최신 시장 점유율 통계이다.
| 날짜 | Nginx (Nginx, Inc.) | Apache (ASF) | OpenResty (OpenResty Software Foundation) | Cloudflare Server (Cloudflare, Inc.) | IIS (마이크로소프트) | GWS (구글) | 기타 |
|---|---|---|---|---|---|---|---|
| 2021년 10월[61] | 34.95% | 24.63% | 6.45% | 4.87% | 4.00% (*) | 4.00% (*) | 22% 미만 |
| 2021년 2월[62] | 34.54% | 26.32% | 6.36% | 5.0% | 6.5% | 3.90% | 18% 미만 |
| 2020년 2월[63] | 36.48% | 24.5% | 4.00% | 3.0% | 14.21% | 3.18% | 15% 미만 |
| 2019년 2월[64] | 25.34% | 26.16% | 해당 없음 | 해당 없음 | 28.42% | 1.66% | 19% 미만 |
| 2018년 2월[65] | 24.32% | 27.45% | 해당 없음 | 해당 없음 | 34.50% | 1.20% | 13% 미만 |
| 2017년 2월[66] | 19.42% | 20.89% | 해당 없음 | 해당 없음 | 43.16% | 1.03% | 15% 미만 |
| 2016년 2월[67] | 16.61% | 32.80% | 해당 없음 | 해당 없음 | 29.83% | 2.21% | 19% 미만 |
참고: (*) 비율은 정수로 반올림되었는데, 이는 십진수 값이 소스 페이지에서 공개적으로 보고되지 않기 때문이다(그래프에서는 반올림된 값만 보고됨).
같이 보기
[편집]각주
[편집]- 1 2 3 Nancy J. Yeager; Robert E. McGrath (1996). 《Web Server Technology》 (영어). Morgan Kaufmann. ISBN 1-55860-376-X. 2023년 1월 20일에 원본 문서에서 보존된 문서. 2021년 1월 22일에 확인함.
- ↑ William Nelson; Arvind Srinivasan; Murthy Chintalapati (2009). 《Sun Web Server: The Essential Guide》 (영어). Pearson Education. ISBN 978-0-13-712892-1. 2023년 1월 20일에 원본 문서에서 보존된 문서. 2021년 10월 14일에 확인함.
- ↑ “What is a web server? - MDN Web Docs”. 《MDN Web Docs》. 2025년 3월 13일. 2025년 3월 20일에 확인함.
- ↑ “What Is a Web Server and How Does It Work? - IT Glossary | SolarWinds” (미국 영어). 《www.solarwinds.com》. 2025년 4월 26일에 확인함.
- ↑ “What are webservers?”. 《Akamai.com》. 2025년 4월 26일.
- ↑ “Study Material on Web Servers - eGyanKosh” (PDF). 《eGyanKosh》. 2025년 3월 20일에 확인함.
- ↑ “Short History of the Web”. 《CERN》. 2025년 4월 9일에 원본 문서에서 보존된 문서. 2025년 3월 20일에 확인함.
- ↑ Zolfagharifard, Ellie (2018년 11월 24일). “'Father of the web' Sir Tim Berners-Lee on his plan to fight fake news” (영국 영어). 《The Telegraph》 (London). ISSN 0307-1235. 2022년 1월 11일에 원본 문서에서 보존된 문서. 2019년 2월 1일에 확인함.
- ↑ “History of Computers and Computing, Internet, Birth, The World Wide Web of Tim Berners-Lee”. 《history-computer.com》. 2019년 1월 4일에 원본 문서에서 보존된 문서. 2019년 2월 1일에 확인함.
- 1 2 3 팀 버너스리 (1992). “WWW Project History (original)”. CERN (World Wide Web project). 2021년 12월 8일에 원본 문서에서 보존된 문서. 2021년 12월 20일에 확인함.
- 1 2 팀 버너스리 (1991년 8월 20일). “WorldWideWeb wide-area hypertext app available (announcement)”. CERN (World Wide Web project). 2021년 12월 2일에 원본 문서에서 보존된 문서. 2021년 10월 16일에 확인함.
- 1 2 Web Administrator. “Web History”. CERN (World Wide Web project). 2021년 12월 2일에 원본 문서에서 보존된 문서. 2021년 10월 16일에 확인함.
- ↑ 팀 버너스리 (1991년 8월 2일). “Qualifiers on hypertext links ...”. CERN (World Wide Web project). 2021년 12월 7일에 원본 문서에서 보존된 문서. 2021년 10월 16일에 확인함.
- ↑ Tim Smith; François Flückiger. “Licensing the Web”. CERN (World Wide Web project). 2021년 12월 6일에 원본 문서에서 보존된 문서. 2021년 10월 16일에 확인함.
- ↑ Ali Mesbah (2009). 《Analysis and Testing of Ajax-based Single-page Web Applications》 (영어). ISBN 978-90-79982-02-8. 2021년 12월 18일에 확인함.
- 1 2 Robert H'obbes' Zakon. “Hobbes' Internet Timeline v5.1 (WWW Growth) NOTE: till 1996 number of web servers = number of web sites”. ISOC. 2000년 8월 15일에 원본 문서에서 보존된 문서. 2021년 12월 18일에 확인함.
- ↑ “NCSA httpd”. NCSA (web archive). 2010년 8월 1일에 원본 문서에서 보존된 문서. 2021년 12월 16일에 확인함.
- ↑ “About the Apache HTTPd server: How Apache Came to be” (영어). Apache: HTTPd server project. 1997. 2008년 6월 7일에 원본 문서에서 보존된 문서. 2021년 12월 17일에 확인함.
- ↑ “Web Server Survey, NOTE: number of active web sites in year 2000 has been interpolated”. Netcraft. 2021년 12월 22일. 2021년 12월 27일에 원본 문서에서 보존된 문서. 2021년 12월 27일에 확인함.
- ↑ “Netcraft: web server software (1996)”. Netcraft (web archive). 1996년 12월 30일에 원본 문서에서 보존된 문서. 2021년 12월 16일에 확인함.
- ↑ “Overview of new features in Apache 2.2” (영어). Apache: HTTPd server project. 2005. 2021년 11월 27일에 원본 문서에서 보존된 문서. 2021년 12월 16일에 확인함.
- ↑ “Overview of new features in Apache 2.4” (영어). Apache: HTTPd server project. 2012. 2021년 11월 26일에 원본 문서에서 보존된 문서. 2021년 12월 16일에 확인함.
- ↑ "Connections, persistent connections: practical considerations". RFC 2616, Hypertext Transfer Protocol -- HTTP/1.1. pp. 46–47. sec. 8.1.4. RFC 2616. https://tools.ietf.org/html/rfc2616#section-8.1.4.
- ↑ “Maximum concurrent connections to the same domain for browsers”. 2017. 2021년 12월 21일에 원본 문서에서 보존된 문서. 2021년 12월 21일에 확인함.
- ↑ “Linux Web Server Performance Benchmark - 2016 results”. RootUsers. 2016년 3월 8일. 2021년 12월 23일에 원본 문서에서 보존된 문서. 2021년 12월 22일에 확인함.
- 1 2 “Will HTTP/2 replace HTTP/1.x?”. IETF HTTP Working Group. 2014년 9월 27일에 원본 문서에서 보존된 문서. 2021년 12월 22일에 확인함.
- 1 2 “Implementations of HTTP/2 in client and server software”. IETF HTTP Working Group. 2021년 12월 23일에 원본 문서에서 보존된 문서. 2021년 12월 22일에 확인함.
- ↑ “Why just one TCP connection?”. IETF HTTP Working Group. 2014년 9월 27일에 원본 문서에서 보존된 문서. 2021년 12월 22일에 확인함.
- 1 2 "Client/Server Messaging". RFC 7230, HTTP/1.1: Message Syntax and Routing. pp. 7–8. sec. 2.1. RFC 7230. https://tools.ietf.org/html/rfc7230#section-2.1.
- 1 2 "Handling Incomplete Messages". RFC 7230, HTTP/1.1: Message Syntax and Routing. p. 34. sec. 3.4. RFC 7230. https://tools.ietf.org/html/rfc7230#section-3.4.
- ↑ "Message Parsing Robustness". RFC 7230, HTTP/1.1: Message Syntax and Routing. pp. 34–35. sec. 3.5. RFC 7230. https://tools.ietf.org/html/rfc7230#section-3.5.
- ↑ https://developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps/Routing [깨진 링크(과거 내용 찾기)]
- 1 2 3 4 5 “Mapping URLs to Filesystem Locations” (영어). Apache: HTTPd server project. 2021. 2021년 10월 20일에 원본 문서에서 보존된 문서. 2021년 10월 19일에 확인함.
- ↑ “Dynamic Content with CGI” (영어). Apache: HTTPd server project. 2021. 2021년 11월 15일에 원본 문서에서 보존된 문서. 2021년 10월 19일에 확인함.
- ↑ Chris Shiflett (2003). 《HTTP developer's handbook》 (영어). Sams's publishing. ISBN 0-672-32454-7. 2023년 1월 20일에 원본 문서에서 보존된 문서. 2021년 12월 9일에 확인함.
- ↑ Spasojevic, Anastazija (2024년 8월 26일). “What Is Common Gateway Interface?” (미국 영어). 《phoenixNAP IT Glossary》. 2026년 3월 18일에 확인함.
- 1 2 3 ASF Infrabot (2019년 5월 22일). “Directory listings” (영어). Apache foundation: HTTPd server project. 2019년 6월 7일에 원본 문서에서 보존된 문서. 2021년 11월 16일에 확인함.
- ↑ “Apache: directory listing to download files”. Apache: HTTPd server. 2021년 12월 2일에 원본 문서에서 보존된 문서. 2021년 12월 16일에 확인함.
- ↑ "Client Error 4xx". RFC 7231, HTTP/1.1: Semantics and Content. p. 58. sec. 6.5. RFC 7231. https://tools.ietf.org/html/rfc7231#section-6.5.
- ↑ "Server Error 5xx". RFC 7231, HTTP/1.1: Semantics and Content. pp. 62-63. sec. 6.6. RFC 7231. https://tools.ietf.org/html/rfc7231#section-6.6.
- ↑ "Introduction". RFC 7235, HTTP/1.1: Authentication. p. 3. sec. 1. RFC 7235. https://tools.ietf.org/html/rfc7235#section-1.
- 1 2 "Response Status Codes: Redirection 3xx". RFC 7231, HTTP/1.1: Semantics and Content. pp. 53–54. sec. 6.4. RFC 7231. https://tools.ietf.org/html/rfc7231#section-6.4.
- ↑ "Successful 2xx". RFC 7231, HTTP/1.1: Semantics and Content. pp. 51-54. sec. 6.3. RFC 7231. https://tools.ietf.org/html/rfc7231#section-6.3.
- ↑ “Caching Guide” (영어). Apache: HTTPd server project. 2021. 2021년 12월 9일에 원본 문서에서 보존된 문서. 2021년 12월 9일에 확인함.
- ↑ “NGINX Content Caching” (영어). F5 NGINX. 2021. 2021년 12월 9일에 원본 문서에서 보존된 문서. 2021년 12월 9일에 확인함.
- ↑ Evangelos P. Markatos (1996). “Main Memory Caching of Web Documents” (영어). Computer networks and ISDN Systems. 2023년 1월 20일에 원본 문서에서 보존된 문서. 2021년 12월 9일에 확인함.
- ↑ “IPlanet Web Server 7.0.9: file-cache” (영어). Oracle. 2010. 2021년 12월 9일에 원본 문서에서 보존된 문서. 2021년 12월 9일에 확인함.
- ↑ “Apache Module mod_file_cache” (영어). Apache: HTTPd server project. 2021. 2021년 12월 9일에 원본 문서에서 보존된 문서. 2021년 12월 9일에 확인함.
- ↑ “HTTP server: configuration: file cache” (영어). GNU. 2021. 2021년 12월 9일에 원본 문서에서 보존된 문서. 2021년 12월 9일에 확인함.
- ↑ “Apache Module mod_cache_disk” (영어). Apache: HTTPd server project. 2021. 2021년 12월 9일에 원본 문서에서 보존된 문서. 2021년 12월 9일에 확인함.
- ↑ “What is dynamic cache?” (영어). Educative. 2021. 2021년 12월 9일에 원본 문서에서 보존된 문서. 2021년 12월 9일에 확인함.
- ↑ “Dynamic Cache Option Tutorial” (영어). Siteground. 2021. 2023년 1월 20일에 원본 문서에서 보존된 문서. 2021년 12월 9일에 확인함.
- ↑ Arun Iyengar; Jim Challenger (2000). “Improving Web Server Performance by Caching Dynamic Data” (영어). Usenix. 2021년 12월 9일에 확인함.
- ↑ Jussara M. Almeida; Virgilio Almeida; David J. Yates (1997년 7월 7일). “WebMonitor: a tool for measuring World Wide Web server performance” (영어). 《First Monday》. doi:10.5210/fm.v2i7.539. 2021년 11월 4일에 원본 문서에서 보존된 문서. 2021년 11월 4일에 확인함.
- ↑ Fisher, Tim; Lifewire. “Getting a 502 Bad Gateway Error? Here's What to Do” (영어). 《Lifewire》. 2017년 2월 23일에 원본 문서에서 보존된 문서. 2019년 2월 1일에 확인함.
- ↑ “What is a 502 bad gateway and how do you fix it?” (영어). 《IT PRO》. 2023년 1월 20일에 원본 문서에서 보존된 문서. 2019년 2월 1일에 확인함.
- ↑ Fisher, Tim; Lifewire. “Getting a 503 Service Unavailable Error? Here's What to Do” (영어). 《Lifewire》. 2023년 1월 20일에 원본 문서에서 보존된 문서. 2019년 2월 1일에 확인함.
- ↑ Fisher, Tim; Lifewire. “Getting a 504 Gateway Timeout Error? Here's What to Do” (영어). 《Lifewire》. 2021년 4월 23일에 원본 문서에서 보존된 문서. 2019년 2월 1일에 확인함.
- ↑ many (2021년 1월 24일). “Slow uploads with HTTP/2” (영어). github. 2021년 11월 16일에 원본 문서에서 보존된 문서. 2021년 11월 15일에 확인함.
- ↑ Junho Choi (2020년 8월 24일). “Delivering HTTP/2 upload speed improvements” (영어). Cloudflare. 2021년 11월 16일에 원본 문서에서 보존된 문서. 2021년 11월 15일에 확인함.
- ↑ “October 2021 Web Server Survey”. Netcraft. 2021년 10월 15일. 2021년 11월 15일에 원본 문서에서 보존된 문서. 2021년 11월 15일에 확인함.
- ↑ “February 2021 Web Server Survey”. Netcraft. 2021년 2월 26일. 2021년 4월 15일에 원본 문서에서 보존된 문서. 2021년 4월 8일에 확인함.
- ↑ “February 2020 Web Server Survey”. Netcraft. 2020년 2월 20일. 2021년 4월 17일에 원본 문서에서 보존된 문서. 2021년 4월 8일에 확인함.
- ↑ “February 2019 Web Server Survey”. Netcraft. 2019년 2월 28일. 2021년 4월 15일에 원본 문서에서 보존된 문서. 2021년 4월 8일에 확인함.
- ↑ “February 2018 Web Server Survey”. Netcraft. 2018년 2월 13일. 2021년 4월 17일에 원본 문서에서 보존된 문서. 2021년 4월 8일에 확인함.
- ↑ “February 2017 Web Server Survey”. Netcraft. 2017년 2월 27일. 2017년 3월 14일에 원본 문서에서 보존된 문서. 2017년 3월 13일에 확인함.
- ↑ “February 2016 Web Server Survey”. Netcraft. 2016년 2월 22일. 2022년 1월 27일에 원본 문서에서 보존된 문서. 2022년 1월 27일에 확인함.
외부 링크
[편집]
위키미디어 공용에 웹 서버 관련 미디어 분류가 있습니다.