제공 : 한빛 네트워크
저자 : Bill Lubanovic
역자 : 추홍엽
원문 : The lighttpd Web Server
최근까지 아파치는 심각한 오픈소스 라이벌이 없었다. Netcraft사의 최근 웹서버 조사에서 한가지 주목할 만한 것이 있다. 언제나처럼 아파치가 정상을 차지하고 있고, Microsoft사의 IIS가 2위, 그리고 꾸준한 인기를 얻어온 unknown이 3위였다. 4위는 Sun사의 Java Web Server(이전까지는 ONE으로, 그이전에는 iPlanet, 그 이전에는 Netscape으로 알려져있었던). 그런데 5위는 1천 4백만 사이트에서 사용하고 있는 lighttpd라는 서버였다. 대체 어디서 나타난 녀석이란 말인가. 이제부터 lighttpd의 역사와 기본 설치 및 설정방법, 그리고 앞으로의 비전에 대해 살펴보려 한다.
이것은 "라이-티-피-디(lite-tee-pee-dee)"라고 발음하며, 짧게는 "라이티(lighty)"라고 부른다. 뭐라고 찾던 간에 웹사이트나 위키, 블로그 혹은 포럼 등에서 이것에 대한 많은 정보를 찾을 수 있다. lighttpd는 적은 자원을 사용하여 높은 성능을 내는 웹서버로서 고안되었다. 이것은 아파치보다 훨씬 적은 메모리를 사용하면서도 일반적으로 아파치보다 속도가 빠르다. lighttpd는 YouTube, Wikipedia, Meebo, 그리고 A List Apart를 포함한 여러 중책 사이트에서 묵묵히 가동되고 있다. lighttpd가 루비 온 레일즈나 트랙(Trac)과 같은 인기 툴들과 함께 아파치를 대신하는 것을 종종 보게 될 것이다.
아파치의 잘못된 점
그 인기에도 불구하고 가끔 아파치는 최상의 솔루션이 아닐 때가 있다. 아파치는 서로 다른 런타임 환경에서 사용할 수 있게 하기 위해 서로 다른 다중-프로세싱 모델(Multi-Processing Models, MPMs)을 제공한다. 선분기(prefork) 모델 -- Linux에서 가장 인기 있다 -- 은 시작시에 여러 개의 아파치 프로세스를 생성하고 이들을 풀에서 관리한다. 이에 대한 대안적인 작업모델은 여러개의 프로세스 대신에 다중 스레드를 사용한다. 비록 스레드가 프로세스보다 가볍긴 하지만, 전체 서버가 스레드에 안전(threadsafe)하지 않으면 이를 사용할 수 없다. 아파치와 mod_php가 스레드에 안전하다고 하지만 서드파티 모듈에 대해 보장되진 않는다. PHP 사이트는 스레드를 쓰는 MPM을 가진 아파치2 사용을 말리고 있다. 이것이 개발자들로 하여금 아파치 1.3에서 2.0으로 이동하는 것을 늦추게 된건지도 모른다. 그러나 선분기 모델은 그 자체에 문제점을 가지고 있는데, 각 프로세스(아파치 + PHP + 서드파티 모듈)가 너무 많은 메모리를 사용한다(30MB도 이상하지 않을 정도다). 여기에 동시에 돌아가는 아파치 프로세스 수를 곱하면, 사용할 수 있는 RAM은 순식간에 사라질 것이다.
lighttpd의 과거
어떤 웹사이트들은 동시에 수천개의 파일을 수행하는데, 메모리와 최대 스레드 또는 프로세스 수는 제한되어 있다. Dan Kegel은 C10K 문제에 관한 그의 페이지에서 수천개의 동시 접속을 다룰때 마주치게 되는 문제들에 대해 자세히 설명했다. 2003년 독일의 MySQL 개발자인 Jan Kneschke는 이 문제에 관해 흥미를 가지게 되었고 올바른 기술에 초점을 맞춤으로써 아파치보다 더 빠른 웹서버를 만들 수 있을 것이라고 믿었다. 그는 단일 스레드와 비블러킹(non-blocking) I/O를 가진 단일 프로세스로서 lighttpd를 고안했다. poll, epoll, kqueue, 혹은 /dev/poll 중 어느 하나를 선택하는 대신에 목표 시스템에서 가장 빠른 이벤트 핸들러를 사용했다. 그리고 read나 write보다는 sendfile 같은 제로카피(zero-copy) 시스템 콜을 채택했다. 몇 개월 후 lighttpd는 아파치보다 더 빠르게 정적 파일들을 수행할 수 있었다.
다음 단계는 동적 어플리케이션(CGI), 특히 PHP를 다루는 문제였다. Kneschke 인터넷 초창기 시절 CGI 수행속도를 향상시키기 위해 Open Market에서 만들었던 FastCGI를 털어냈다. 각각의 호출상에서 웹서버가 똑같은 외부 CGI 프로그램을 시작하는 대신, FastCGI는 본질적으로 CGI 어플리케이션을 먼저 실행시키고 자신과 웹서버 사이에서의 통신을 다루는 데몬이었다. 이것도 빨랐지만 후에 펄과 PHP가 아파치에 모듈로 흡수되면서 더 빨라졌고 아파치의 내부 HTTP 실행 단계에 접근 할 수 있게 되었다. 아파치용 FastCGI는 등한시 되었지만 후에 lighttpd에 추가되고 PHP와 연결되면서 FastCGI의 성능은 mod_php를 쓰는 아파치와 상응하거나 그를 초월하게 되었다. 추가적으로 lighttpd구현에는 자동 로드밸런싱이 추가되었다.
lighttpd 생태계는 가상 호스트, 리플렉션, URL 재작성, 인증 및 다른 웹스런 것들을 관리하기 위한 모듈로 확장되어 왔다. 대부분의 용도로는 아파치로 할 수 있는 어떠한 것도 lighttpd에서 할 수 있다. 다음 몇개의 장들에서 lighttpd 설치와 설정하는 법들을 아파치의 경우와 함께 살펴보려 한다.
lighttpd 설치
lighttpd를 설치하고 이리저리 쿡쿡 찔러보도록 하자. 위키의 설치 페이지에서는 다양한 리눅스 배포판에 대한 바이너리 혹은 소스 설치 예를 보여주고 있다. 단순 무식한 남성미가 넘치는 개발자들(여러분들을 말하는 것은 아니다)을 위한, 전체 소스 인스톨은 다음과 같이 한다.
# wget http://www.lighttpd.net/download/lighttpd-1.4.13.tar.gz
# tar xvzf lighttpd-1.4.13.tar.gz
# cd lighttpd-1.4.13
# ./configure
# make
# make install
이는 /usr/local 아래에 lignttpd를 설치할 것이다. 만약 빌드가 실패하면, 설치에 앞서 필요한 pcre과 zlib 개발 패키지가 시스템에 설치되어 있는지 확인하라.
lighttpd를 수동으로 시작하거나 종료하고 싶으면 여기서 끝이다. lighttpd를 아파치처럼 서비스로서 인스톨 하려면, init 스크립트를 수정하고 인스톨한다.
# sed -e "s/FOO/lighttpd/g" doc/rc.lighttpd > lighttpd.init
# chmod a+rx lighttpd.init
# cp lighttpd.init /etc/init.d/lighttpd
# cp -p doc/sysconfig.lighttpd /etc/sysconfig/lighttpd
# install -Dp ./doc/lighttpd.conf /etc/lighttpd/lighttpd.conf
# chkconfig lighttpd on
기본 설정
lighttpd 설정 파일의 문법은 아파치와의 눈에 보이는 가장 큰 차이점이라 할 수 있다. 위키의 설정 페이지 예제는 아파치의 XML스러운 httpd.conf보다 펄(혹은 PHP나 파이썬)쪽에 더 가까워 보인다. 정적인 파일들을 지닌 간단한 웹사이트의 경우, 아파치의 경우와 같이 도큐먼트 루트, 로그파일명, 리눅스 사용자와 그룹명 등을 명시할 필요가 있다. 다음의 아파치 설정(httpd.conf)과 lighttpd 설정(lighttpd.conf)은 대등하다.
Apache:
DocumentRoot /var/www/html
CustomLog /var/www/logs/access
ErrorLog /var/www/logs/error
User www
Group www
lighttpd:
server.document-root = "/var/www/html"
accesslog.filename = "/var/www/logs/access"
server.errorlog = "/var/www/logs/error"
server.username = "www"
server.groupname = "www"
server.modules = ( "mod_accesslog" )
lighttpd는 아파치와 유사한 인클루드 메커니즘을 가지고 있기 때문에 lighttpd.conf가 더 커질 필요가 없다. 추가적인 모듈을 사용하기 위해, 그 기능을 켜고 그 옵션을 설정하면 된다. 아파치는 LoadModule로 이것을 켜지만, lighttpd는 단지 server.modules 배열에서 주석처리 안된 모듈명을 인클루드 한다. 그보다 훨씬 필요한 유일한 하나는 mod_accesslog이다.
인증(Authentication)과 권한부여(Authorization)
lighttpd는 .htaccess 파일을 지원하지 않으므로 모든 설정을 lighttpd.conf 파일 혹은 그것이 인클루드하는 파일에 명시할 필요가 있다. 이것은 기본적인 아파치 user 파일을 잘 이해하고 인증을 소화한다. 그러나 group 파일 지원은 아직 구현되지 않았다. 다음은 special이라 부르는 최상위 디렉토리에 비밀번호 보호를 거는 방법이다.
Apache:
AuthName "My Special Directory"
AuthType Basic
AuthUserFile /var/www/passwords/users
Order deny,allow
require valid-user
lighttpd:
auth.backend = "htpasswd"
auth.backend.htpasswd.userfile = "/var/www/passwords/users"
auth.require = ( "/special/" =>
(
"method" => "basic",
"realm" => "My Special Directory",
"require" => "valid-user"
)
)
가상 호스트
이번엔 열심히 일하면서도 진가를 인정받지 못하는 여러분의 웹서버를 위한 또 다른 과제다: scratch.example.com과 sniff.example.com로 불리우는 두 사이트를 관리하는 일이다.
Apache:
NameVirtualHost *
ServerName "scratch.example.com"
DocumentRoot "/var/www/hosts/scratch/docs"
ServerName "sniff.example.com"
DocumentRoot "/var/www/hosts/sniff/docs"
lighttpd:
$HTTP["host"] == "scratch.example.com" {
server.document-root = "/var/www/hosts/scratch/docs/" }
$HTTP["host"] == "sniff.example.com" {
server.document-root = "/var/www/hosts/sniff/docs/" }
이는 힘들게 일하는 방식이다. 만약 여러분이 많은 호스트들을 관리한다면, 가상 호스트 모듈로 입력을 더 줄일 수 있다:
Apache:
LoadModule vhost_alias_module modules/mod_vhost_alias.so
VirtualDocumentRoot /var/www/hosts/%1/docs
lighttpd:
server.modules = ( ..., "mod_evhost", ... )
evhost.path-pattern = "/var/www/hosts/%3/docs"
Server-Side Includes (SSI)
동적 컨텐츠를 향한 기초 걸음마로, 파일끝에 .shtml를 붙여서 SSI를 켜는 것은 쉽다.
Apache:
AddHandler server-parsed .shtml
lighttpd:
server.modules = ( ..., "mod_ssi", ... )
ssi.extension = ( "shtml" )
PHP
lighttpd 는 CPU 집중적인 동적 컨텐츠를 또 다른 프로세스에 덜어줌으로써 정적 파일 처리량을 최적화 한다. PHP를 내부적으로 처리하기보다는 아파치가 mod_php를 쓰는 것처럼, lighttpd도 FastCGI에 그것을 맡긴다. 이러한 설정 부분은 지루하고 활기없는 .php파일들을 활기찬 PHP 스크립트로 변화시킨다. 이곳과 같은 패밀리 사이트에서 보는 것 보다 좀 더 즐겁게 세부적인 것을 보려면, 이 페이지를 참조하라.
Apache:
LoadModule php5_module modules/libphp5.so
AddType application/x-httpd-php .php
lighttpd:
server.modules = ( ..., "mod_fastcgi", ... )
fastcgi.server =
( ".php" =>
( "localhost" =>
(
"socket" => "/tmp/php-fastcgi.socket",
"bin-path" => "/usr/local/bin/php"
)
)
)
lighttpd의 장점
lighttpd 는 압축, 디렉토리 목록나열, 사용자 디렉토리, SSL, WebDAV, 그리고 URL 다시쓰기(rewriting)나 리다이렉션에 대해 아파치와 동등한 모듈을 포함한다. 이러한 것들에 대해서는 웹사이트 상에서 읽어볼 수 있다. lighttpd에만 있는 다른 흥미로운 모듈들도 있다.
조그만 YouTube가 되고 싶다면, mod_flv_streaming 모듈을 사용하여 수천개의 플래시 무비를 평행하게 스트리밍할 수 있다. 비록 YouTube는 아직 이 모듈을 사용하지는 않지만, 정적 파일들에 대해서는 lighttpd로 수행한다.
여러분이 만약 수많은 플래시 파일들을 보유한 사이트를 가지고 있다면 핫링킹(hotlinking)에 대해 보호하는 것은 어떤가. 어떠한 파일 타입에도 적용가능한 lighttpd의 해결책은 mod_secdownload이다. 특별한 URL을 생성하는 함수를 작성하여 이 모듈이 그 URL을 가지고 주어진 파일을 주어진 시간만큼 접근할 수 있는 권한을 주는 것이다.
Lighty 1.5.0
Kneschke는 현재 1.5.0 버전에 박차를 가하고 있다. 이 버전에서는 성능과 유연성이 향상될 것이다. 새로운 I/O 서브시스템은 스레딩(여기서는 스레드가 맞을 듯 하다)과 비동기 I/O -- POSIX나 리눅스 네이티브, 혹은 glib 2.0에 있는 userland gthread wrapper -- 를 통해 향상될 것이다.
mod_proxy_core는 mod-proxy, mod-fastcgi, mod-scgi 세 개의 백-엔드(backend) 모듈을 통합한다. 실제 처리에서 프로토콜을 분리함으로써 로드밸런싱 및 실패처리(fail-over), keep-alive, 기본 프록시 기능에 내부 큐를 사용하는 것들이 가능해진다.
mod_magnet라 부르는 최근의 추가사항은 lighttpd의 미래에 커다란 역할을 할 것으로 기대된다. 이것은 URL 재작성이나 컨텐츠 생성을 포함하여 HTTP 요청과 응답의 서로다른 단계에 접근하게 할 수 있다. 한가지 흥미로운 선택은 아파치의 mod_rewrite와 같은 복잡한 문법 보다는 Lua라는 내장된 스크립트 언어를 사용한다는 것이다. 우리는 개발자들이 이것을 좋아하게 되던지 아니면 아파치의 친숙하지만 때론 어려운 rewrite 규칙에 고착하게 되는지 보게될 것이다.
Lighty는 어디로 가고 있는가?
Kneschke는 lighttpd의 미래가 다음 두가지 경우를 따를 것이라 기대한다:
- 고성능, 고사용성의 컨텐츠 전송
- 임베디드 서버, 크로스 컴파일, 적은 메모리 사용
1.5.0 이후에, mod_magnet는 좀더 많은 동적 서버 설정을 제공할 것이다. 이는 .htaccess을 지원하지 않아 lighttpd로 옮겨가길 거부해온 일부 아파치 개발자들을 끌어들일 것이다. 필자는 Comet--역 Ajax의 한 종류, 새로운 데이터가 있을때 서버가 클라이언트를 업데이트한다--에 대한 지원이 계획되길 고대하고 있다. 이것은 웹 대쉬보드나 채팅, 혹은 다른 상당히 인터랙티브한 어플리케이션들을 가지고 있다. Ajax와 Comet으로 웹 어플리케이션은 좀 더 전통적인 GUI 어플리케이션과 같은 모습을 할 수 있다. 그러나 이러한 새로운 기능들이 아니더라도 lighttpd는 벌써 아파치의 강력한 경쟁상대--특히 메모리가 제한되어 있거나 많은 정적파일들로 구성된 작업량에 대해서--이다. 가벼운게 좋은거다.
저자 Bill Lubanovic는 70년대에 UNIX로 소프트웨어 개발을 시작했고, 80년대에는 GUIs, 90년대에는 웹개발을 해왔다. 그는 현재 한 풍력 관련 회사에서 웹 비주얼 작업을 하고 있다.