До недавнего времени, Apache не имел серьезных конкурентов с открытым исходным кодом. В последнем обзоре веб-серверов, проведенном Netcraft, мы можем видеть нечто новое. Как и обычно, Apache возглавляет список, Microsoft IIS второй, а знаменитый unknown — третий. Четвертым является Sun Java Web Server (ранее известный как ONE, бывший iPlanet, бывший Netscape). Но пятым номером, обслуживая около 1,4 миллиона сайтов, нечто под названием lighttpd. Откуда это взялось? Мы изучим историю lighttpd, начальную установку и настройку, а также некоторые взгляды на будущее проекта.
Вы можете произносить это название как лайт-ти-пи-ди или, меньше плюясь, лайти. Как бы вы не говорили/выплевывали название этого веб-сервера, вы найдете много информации на его веб-сайте, вики, блоге, или на форумах. lighttpd проектировался как высокоэффективный веб-сервер с низким использованием ресурсов. Он использует гораздо меньше памяти, чем Apache и, как правило, работает быстрее. lighttpd тихо усиливает много высоконагруженных сайтов, включая YouTube, Wikipedia, Meebo и A List Apart; вы увидете, что он часто используется вместо Apache вместе с популярными инструментами, такими как Ruby on Rails и Trac.
Что не так с Apache?
Не смотря на свою популярность, иногда использование Apache не является лучшим решением. Apache предоставляет различные Мульти-Процессные Модели (MPMs) для использования в различных средах работы. Модель prefork — наиболее популярная в Linux — создает определенное число процессов Apache при его запуске и управляет ими в пуле. Альтернативной моделью является worker, которая использует несколько потоков вместо процессов. Хотя потоки легче, чем процессы, вы не можете их использовать до тех пор, пока весь ваш сервер не будет безопасен для потоков (thread safe). Хотя Apache и mod_php — безопасны для потоков, это не гарантирует, что все сторонние модули могут использоваться. Сайт PHP не одобряет использование Apache 2 с потоковой MPM; это замедляет переход разработчиков с Apache 1.3 на 2.x. А модель prefork имеет свои проблемы: каждый процесс (Apache + PHP + сторонние модули) занимает много памяти (30 МБ не является чем-то необычным). Когда вы увеличиваете число одновременных процессов Apache, доступная вам память может быстро кончиться.
lighttpd в тумане.
Некоторые сайты параллельно обрабатывают тысячи файлов, будучи при этом ограничены в памяти и максимальным числом потоков или процессов. Дэн Кегел (Dan Kegel) подробно описал проблемы при обработки тысяч одновременных запросов на своей странице в C10K problem. В 2003 немецкий разработчик MySQL по имени Ян Кнешке (Jan Kneschke) заинтересовался в этой проблеме и решил, что сможет написать веб-сервер, который будет быстрее Apache, сфокусировавшись на правильных методиках. Он спроектировал lighttpd как один процесс с одним потоком и неблокирующимся вводом-выводом. Вместо select, он использовал быстрейшие обработчики событий в целевой системе: poll, epoll, kqueue или /dev/poll. Он выбрал безэкземлярные системные вызовы, как sendfile вместо read и write. В течение нескольких месяцев lighttpd стал обрабатывать статичные файлы быстрее, чем Apache.
Следующим шагом было обработать динамические (CGI) приложения, в частности PHP. Кнешке сдул пыль с FastCGI, разработанном Open Market в самых ранних днях существования интернета, в целях улучшения работы CGI. Вместо того, чтобы веб-сервер запускал ту же внешнюю CGI-программу при каждом вызове, FastCGI по существу был демоном для предварительного запуска CGI-приложения и управления связью между ним и веб-сервером. Это было быстрее, но Perl и PHP позже были внедрены в Apache в качестве модулей, которые были даже быстрее и получали доступ к внутренним действиям Apache по обработке HTTP. FastCGI для Apache стал пренебрегаться, но после того, как он был добавлен в lighttpd и к нему подключили PHP, его производительность равнялась или превышала ту, что показывал Apache с mod_php. В качестве дополнения, в реализацию lighttpd была добавлена автоматическая балансировка загрузки.
lighttpd был также расширен модулями для управления виртуальными хостами, переадресации, перезаписи URL, аутентификации и других полезных вещей. В большинстве случаев, все, что вы можете сделать в Apache, вы можете сделать в lighttpd. В следующих разделах я покажу, как установить и настроить lighttpd с оглядкой на Apache.
Установка lighttpd.
Давайте установим lighttpd и поковыряемся в нем образными палочками. Страница установки на вики дает примеры установки бинарников или из исходников для различных дистрибутивов Linux. Для разработчиков с волосатой грудью (эти волосы не обязательно должны быть вашими), полная установка из исходников выглядит так:
# 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
Это установит lighttpd в /usr/local. Если сборка не удалась, проверьте, что требуемые пакеты разработки pcre и zlib установлены в вашей системе.
Если вы хотите запускать и останавливать lighttpd вручную, то вперед. А чтобы установить lighttpd как сервис вроде Apache, отредактируйте и установите скрипт инициализации:
# 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 может иметь отличия от Apache. Примеры со страницы настройки из вики выглядят больше похожими на Perl (или PHP, или Python), нежели чем на стиль XML httpd.conf в Apache. Для простого сайта со статическими файлами, вам нужно указать те же вещи, что и в Apache: document root, расположение access и error логов и имена user и group для работы сервера. Вот эквивалентные варианты Apache (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 похож на тот, что в Apache, так что файл lighttpd.conf не должен расти. Чтобы использовать дополнительный модуль, вам нужно включить его и установить его опции. В Apache это делается с помощью LoadModule, а lighttpd просто включает незакомментированный модуль в массиве server.modules. Пока что вам нужен только mod_accesslog.
Аутентификация и авторизация.
lighttpd не поддерживает файлы .htaccess, так что вам нужно указывать все настройки в файле lighttpd.conf, или в файлах, к нему подключенным. Он понимает файлы пользователей Apache для простой и общей аутентификации, но поддержка групповых файлов ещё не реализована. Вот пример, как защитить паролем высокоуровневый каталог под названием 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)
Первым шагом к динамическому контенту будет простое включение SSI для файлов с расширением .shtml:
Apache:
AddHandler server-parsed .shtml
lighttpd:
server.modules = ( ..., "mod_ssi", ... )
ssi.extension = ( "shtml" )
PHP
lighttpd оптимизирует производительность обработки статичного файла с помощью выгрузки динамического контента, загружающего ЦПУ в другой процесс. Вместо обработки PHP внутри, как делает Apache с 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 включает в себя модули, эквивалентные модулям Apache для сжатия, просмотра каталогов, пользовательских каталогов, SSL, WebDAV, перезаписи URL и переадресации. Вы можете прочитать об этом на сайте. Другие интересные модули lighttpd являются уникальными.
Если вы хотите сделать мини-YouTube, мы можете параллельно показывать тысячи флеш-роликов с помощью модуля mod_flv_streaming. YouTube обрабатывает его собственные статические файлы с помощью lighttpd, хотя ещё не использует этот модуль.
Если у вас есть такой сайт с большим количеством флеш-файлов, как вам защититься от хотлинкинга? Решением этой проблемы в lighttpd, подходящим для любых типов файлов, является mod_secdownload. Вы пишете функцию (примеры по ссылке написаны на PHP и Ruby) для генерирования специального URL, а модуль обрабатывает этот URL для предоставления доступа к определенному файлу на определенный период времени.
Лайти Один Пять Ноль.
В данный момент Кнешке разрабатывает версию 1.5.0, которая увеличит производительность и гибкость. Новая подсистема ввода-вывода улучшает производительность с помощью тредов (в данном случае треды имеют смысл) и асинхронный ввод-вывод, будь то POSIX, собственный в Linux или пользовательская оболочка gthread в glib 2.0.
Модуль mod_proxy_core объединяет три бэкенд модуля: mod-proxy, mod-fastcgi и mod-scgi. Отделение протоколов от основной обработки дает балансировку нагрузки (четырех видов!), преодоление отказа, удержание соединения и внутреннее формирование очереди к основной функции прокси.
Ожидается, что новый модуль под названием mod_magnet сыграет большую роль в будущем lighttpd. Он дает доступ к разным фазам HTTP запроса и ответа, включая задачи вроде перезаписи URL и генерации контента. Интересным выбором было использование в нем встроенного скриптового языка Lua вместо сложной грамматики, как в mod_rewrite Apache. Посмотрим, понравится ли это разработчикам, или они будут придерживаться знакомым, хотя иногда и сложным, правилам Apache.
Куда Лайти?
Кнешке видит будущее lighttpd в двух направлениях:
— Высокопроизводительные, широкодоступные поставщики контента
— Встроенные сервера, кросс-компиляция, использовать мало памяти
После 1.5.0, mod_magnet будет предоставлять больше динамической конфигурации сервера. Это может привлечь некоторых пользователей Apache, отказавшихся от перехода на lighttpd из-за отсутствия поддержки .htaccess. Я с нетерпением жду запланированную поддержку Comet — обратная сторона AJAX, в которой сервер обновляет клиента при поступлении новых данных. Это имеет приложения к панелям управления веб-приложений, чатам и другим высокоинтерактивным приложениям. С помощью AJAX и Comet, веб-приложения могут выглядеть гораздо более похожими на приложения с традиционным GUI. Но даже без этих новых возможностей, lighttpd уже является сильным конкурентом для Apache, особенно при ограничениях в памяти или обработке множества статических файлов. Легкость — это хорошо.