суббота, 11 июня 2011 г.

Оптимизация взаимодействия веб-клиента и сервера - Статический контент


Введение

Зачастую достаточно лишь позаботиться об интенсивном кэшировании статики на стороне клиента (включая сюда кэширующие прокси-серверы интернет-провайдеров), и количество запросов на статику оказывается относительно мало, так что оптимизация этих и так "легких" запросов становится бесполезной. Но что делать, если запросов все равно очень много? Это может быть вызвано как характером контента (например, фотогалерея), так и просто высокой посещаемостью, особенно когда много уникальных посетителей.

Легковесность

Минималистичные веб-сервера для раздачи статики совсем или почти совсем не требуют настройки, обеспечивая при этом высокую производительность. Одним из действительно простых и эффективных веб-серверов для отдачи статического контента является fnord:
Программа fnord представляет собой миниатюрный HTTP сервер(15k размером), запускаемый посредством TCP суперсервера tcpsvd, tcpserver или другого. fnord хорошо оптимизированный и быстрый, поддерживает передачу методом sendfile и постоянные соединения (keep-alive), CGI, виртуальные домены, и докачку (content-ranges). Дополнительно встроена возможность подмены содержимого на лету (html - html.gz, or gif - png), и генерация индекса директории.
Особенно интересен fnord тем, что работа с TCP делегирована так называемому TCP суперсерверу. В любой UNIX/Linux системе есть встроенный TCP суперсервер, но мы обратимся к помощи более производительного tcpserver:
tcpserver ожидает входящие соединения от TCP клиентов. Для каждого соединения запускается программа, указанная аргументом командной строки, при этом дескриптор 0 принимает данные из сети и дескриптор 1 передает данные в сеть. Также tcpserver устанавливает значения нескольких переменных окружения.
Как и некоторые другие экстремально компактные программы, tcpserver и fnord следуют так называемому UNIX-way и умеют выполнять лишь одну задачу, зато делают это хорошо. Демон tcpserver слушает указанный порт, и для каждого входящего соединения (на каждый HTTP-запрос) вызывает отдельный экземпляр fnord, который читает содержимое HTTP-запроса на stdin и возвращает результат (HTTP-заголовки и тело ответа) на stdout. Запускается веб-сервер, к примеру, по адресу localhost:8888 и для текущей директории следующим образом:
tcpserver localhost 8888 /usr/sbin/fnord .
В консоль будет выводиться лог всех соединений.

Быстродействие

И в самом деле, легковесный веб-сервер может работать без какой-либо настройки и без конфигурационного файла, но что же будет с производительностью? Для ответа на интересующий нас вопрос сравним веб-сервера по количеству обрабатываемых в секунду запросов (TPS) в зависимости от размера запрошенного файла при 50-ти конкурентных клиентских подключениях. Для каждого вебсервера мы ограничимся конфигурацией по умолчанию из дистрибутива debian squeeze, для работы на одном процессорном ядре это достаточно хороший выбор. Так как размер HTTP заголовков составляет сотни байт, то и тестирование передачи файлов размером менее килобайта практического смысла не имеет.Для тестирования я выбрал несколько популярных веб-серверов. Скрипт для тестирования можно взять по ссылке dload.tcl. Вот какие результаты были получены:
File sizeAolserver/4.5.1Apache2/2.2.15Fnord/1.10Lighttpd/1.4.26Nginx/0.7.65
1000812633682853885
5000724574674843959
10000719629671840866
50000556517608766853
100000386469557665742
500000163296333321305
100000079127135156147

или на графике


Потратив лишь минуту своего времени на запуск веб-сервера fnord, мы получили результат на уровне больших и сложно настраиваемых решений. Не будем углубляться в рассмотрение среднего времени ожидания обработки запроса, замечу лишь, что для связки tcpserver + fnord этот параметр на уровне результатов Nginx и Lighttpd (подробности смотрите в файлах dload.log в прикрепленных к статье ресурсах). Думаю, для многих такой результат оказался неожиданным. Оставляя "за бортом" философские вопросы, мы приходим к следующему выводу - оправдано использование или экстремально простого веб-сервера для статики (такого, как fnord и некоторые другие), или же следует проводить комплексное тестирование и всерьез заниматься настройкой, прежде чем выбирать одно из более сложных решений, таких как Nginx, Lighttpd, etc.

Безопасность

В целях защиты нашей системы крайне желательно, чтобы веб-сервер не имел возможности записи на диск (для защиты от перегрузок при DDOS и взлома через уязвимости в коде работы с файловой системой) и мог запускаться в chroot. При необходимости сохранения лога запросов следует его получать с stdout или в syslog. Перечисленным требованиям удовлетворяет fnord, причем запуск в chroot не требует никаких дополнительных действий. "Большие" веб-сервера придется дополнительно настраивать, чтобы они не пытались писать логи самостоятельно, а поместить их в chroot зачастую непросто.

Комментариев нет:


(C) Alexey Pechnikov aka MBG, mobigroup.ru