Записи с тегом «apache»

Python-хостинг: издержки производства

Хостинг python приложений имеет некоторые нюансы, не всегда удобные и приятные для хостера. Мы уже больше года предоставляем python-хостинг и столкнулись с рядом особенностей. Да, не все в нашем мире идеально :-)

Вся суть в способах связки python-приложения с веб-сервером. С тех пор как php прочно вошел и закрепился в среде веб-разработчиков, его постоянно стали сравнивать с другими языками программирования, применимыми для написания веб-приложений. В том числе сравнивали и производительность. Естественно скорость работы php-парсера была высока по сравнению с perl-кодом, работающим через cgi. Да и вообще cgi стандарт себя уже изживал.

Поэтому серверные веб-технологии пошли двумя основными направлениями в плане сопряжения программной части с веб-сервером:

  1. разработка всяких mod_* — встроенных интерпретаторов в веб-сервер;
  2. переботка стандарта cgi с целью увеличения производительности (FastCGI);
Оба направления популярны и успешны по сей день, т.к. у каждого есть свои плюсы и минусы. Переходя на детали о Python, хочется сделать отдельную заметку общего плана.

В тредовой (thread) модели python есть такое понятие как Interpreter Lock. Это когда тред блокирует интерпретатор на определенное время (пока не выполнит операцию, выполнит определенное кол-во инструкций или не пройдет таймаут). В принципе этот метод разделения ресурсов вполне хорошо работает на практике. Но в случаем с хостингом есть свои нюансы...

Представте вполне реальную картину. Веб сервер (Apache) с встроенным mod_python обслуживает 50 python-приложений. Если апач работает в тредовом режиме, тогда и mod_python тоже (апач настраивается на тредовый режим через опции компиляции, а модуль уже при сборке сам определяет в каком режиме работает апач и собирается в этом же режиме). Теперь сама ситуация: 50 веб-сайтов смогут вполне создать нагрузку 1-5 запросов в секунду, а на каждый процесс апача у нас приходится, например, по 25 тредов и одному интерпретатору python. Теперь вспомним про Interpreter Lock и прикинем какие могут быть ситуации. В общем говоря в тредовом режиме mod_python работает достаточно нестабильно. Выглядеть это будет как таймауты (код будет долго ждать разблокировки интерпретатора).

При работе в fork() режиме веб-сервера, проблема блокировок снимается (т.к. на каждое соединения клиента выделяется отдельный процесс веб-сервера и следовательно отдельный интерпретатор), но возникает проблема с экономией оперативной памяти. Т.к. каждый процесс потребляет значительное кол-во памяти (от 20 до 50 Мб ориентировочно).

Теперь вспомним про второй способ сопряжения приложенияс веб-сервером и подумаем о связке не встроенным способом — т.е. через популярный FastCGI. Веб-сервер в этом случае разгружается и никак практически не зависит от стабильности приложения. Т.е. конечный пользователь в любом случае получит или запрашиваемый результат или страницу с ошибкой, что намного лучше таймаута без каких либо объяснений. В этом случае сам веб-сервер может работать в тредовом режиме и экономить память. Но есть другая проблема. Каждое отдельное python-приложение будет запущено отдельным процессом и будет также потреблять память, что в итоге может дать не экономию, а большие затраты.

Интересно что приложение запущенное в режиме FastCGI может также работать в тредовом и fork() режимах, что соответственно влияет на потребление ресурсов. В тредовом режиме проблемы остаются те-же что и с mod_python. Только кол-во запросов к отдельному FastCGI-процессу в принципе сокращается, что дает меньшую вероятность таймаута в связи с блокировкой интерпретатора.

Подводя итог. Хочу отметить что идеального решения нет. Для каждых отдельных случаев нужно разрабатывать решения (чем мы в принципе и занимаемся). Просто имея эту информацию, Вы сможете сами представить при написании Вашего проекта в каком окружении его лучше запускать. Следовательно Вы сможете его правильно спроектировать и оптимизировать.

Желаем успехов в разработке!

Ruby on Rails на хостинге

Мы начали поддержку Ruby on Rails на нашем хостинге. В скором будующем думаю ещё появяться пару тестовых сайтов с новомодными фичами, которые принято иногда называть Web2.0 :) На данный момент ещё оптимизируется работа ruby и python на сервере через mod_fastcgi + apache2. Если будет время написать о производительности постараюсь выложить результат сюда.

Апдейт софта на сервере httpd

Обновился следующий софт до версий:
  • apache-2.0.55
  • php4-4.4.2
  • mysql-4.1.16
  • postfix-2.2.8
Приятной и стабильной работы! :)

Мониторинг хостингового сервера

Решил поделиться опытом по этой теме. Значит у меня задача звучала примерно так: "не сложный клиент-серверный монитор загрузки сервера с веб-интерфейсом". Если конкретезировать то попросту рисовалка графиков и желательно сделанная на rrdtool. Начал как всегда с гугления и freshmeat.net. В итоге остановился на двух интересных софтинах. Первая cacti (кактус типа). Сделана на rrdtool + php + cactid (написанный на Си даемон-poller, который опрашивает хосты). Использование cactid - опционально. Для хранения конфигурации используется MySQL. Софтина позиционируется автором как комлексное средство монитроинга для сетей локального и глобального масшатаба с размахом до тысячи хостов. Мои запросы оказались поскромнее, поэтому пришлось отказаться от неё. Но в принципе очень стоящая вещь: гибкость на высоком уровне, мониторить может почти всё что угодно (не только стандартные заготовки по параметрам, которые кстати позволяют и так чуть ли не всё мониторить, есть framework для написания своих скриптов). Для сбора статистики по сети с хостов пришлось бы поднимать ещё snmpd - тоже минус. Вторая софтина - symon. На порядок проще. Рисует тоже через rrdtool и веб-интерфейс работает на php. Но своей простотой она меня и привлекла. В комлекте получается три компоненты: symon - локальный даемон для сбора статистики на хосте, symux - серверный даемон для сбора статистики с хостов и syweb - веб-интерфейс. Всё в принципе очень быстро поднялось. Вся конфигурация в текстовых файлах, взаимодействие symon и symux по tcp. Думаю что этот вариант подойдёт и для больших сетей хостов в 100. Главный минус этого варианта - мониторинг только unix-серверов, с устройствами (например switches, cisco routers) он не заработает, SNMP не умеет. Тут как раз выигрывает cacti. Но на данный момент нам как раз и нужно мониторинг только unix-серверов. В итоге мы получили мониторинг загрузки I/O на дисках, процессора, памяти, сетевых интерфейсов, системных буферов (mbuf), кол-ва и состояния процессов Apache, файервола (OpenBSD PF в нашем случае).

Тестирование производительности Apache2 (часть 1)

Первый интересующий меня вопрос при тестировании был "какое количество соединений сможет отработать корректно апач на статическом контенте". Начнём с того что отличительная фича работы apahce2 с запросами это возможность использования тредов. Напомню, что в 1-ой версии апач на каждое соединение делал fork процесса, во 2-ой ветке есть возможность собрать его со старой схемой обработки, но было бы глупо на продакшене не воспользоваться тредовой сборкой. Кому интересно можно почитать в официальной документации апача про многопоточность и мультипроцессные модули. В моём варианте апач был собран с многопоточным модулем worker. Вопрос тюнинга немного не в топик, обсудим его позже подробно. Ещё одно примечание - количество соединений, которое может отработать апач во многом ещё зависит от тюнинга ОС (в нашем случае это FreeBSD) об этом тоже отдельно. Утилита, которой я тестировал называется siege, она позиционриуется автором как стресс-тестер для веб-сервера, что как раз нам и надо. Скажу от себя что утилита вполне справляется со своим предназначением и была выбрана мной из-за простоты использования, гибкости и подробных отчётов. Теперь о процессе тестирования. Для начала я заготовил файлы разного размера на веб-сервере (размер почти произвольный), я брал вариации маленьких файлов до пол-мегабайта и один больше 8 мегабайт (кеш на винте был 8 мегабайт); потом сгенерировал текстовый файл с ссылками. Прочитав мануал по siege настроил конфиг (командой siege.config можно создать темплейт конфига - .siegerc в домашней директории, откуда он и будет читаться). Мои рекомендации по конфигу:
  1. переключить connection в режим close (keep-alive был по умолчанию) - как ни печально, но у меня siege не захотел нормально отработать keep-alive, с этим я ещё поразбераюсь и может что-то отдельно напишу;
  2. установить адекватный concurrent - это количество воображаемых пользователей "гуляющих" по ссылкам, которые генерирует siege;
  3. установить путь к файлу содержащему ссылки (если вы работаете больше чем с одним url) - директива file;
  4. установить время тестирования директивой time;
  5. рекомендую использовать директиву internet для рандомного перебора url-ами из списка (симуляция реальных запросов);
  6. timeout выбирайте на свой вкус, желательно чтоб он был согласован с таймаутом апача и был приближен к таймаутам браузеров.
Все опции можно задавать через ключи в командной строке, но чтоб не запутаться лечге прописать умолчания в конфиге. В результате можно получить следующую интересную статистику:
  • среднее время ответа сервера на запрос;
  • среднее кол-во транзакций в секунду (отработанных запросов);
  • пиковое кол-во одновременных запросов в секунду, после которого производительность апача начинает уменьшаться;
  • процентное отношение корректно обработанных запросов к общему кол-ву запросов;
  • кол-во необработанных запросов (не завершённых).
Публиковать свои результаты думаю не стоит, т.к. аппаратная и программная часть всё-равно у всех будет значительно отличаться. Может будут примеры к статьям о тюнинге самого апача и FreeBSD. Вообщем первая часть на этом заканчивается. To be continued... :-)