Сравнение эффективности способов запуска веб-приложений на языке Python

    Последнее время в области веб-разработок стал набирать популярность язык программирования Python. Однако, массовому распространение Python мешает проблема эффективного запуска приложений на этом языке. Пока, в большинстве случаев, это удел выделенных или виртуальных серверов. Модульные языки в отличии от монолитного в базовой функциональности php на каждый запрос подгружают как минимум runtime-библиотеку, а как максимум — ещё несколько десятков запрашиваемых пользователем модулей. Поэтому классический подход наподобие mod_php для Python и Perl не очень уместен, а держать приложение постоянно в памяти было дороговато. Но время движется, техника стала мощнее и дешевле, и уже достаточно давно можно спокойно говорить о постоянно запущенных процессах с приложением в рамках массового хостинга.

    О чём тут

    Время от времени, в сети появляются различные предложения как запустить приложение на Python. Например, недавно хостинг Джино уникально поправил mod_python и предложил хостинг именно с его помощью. Следом за ним, некий хостинг Locum вообще отринул mod_python с его безопасностью (создаётся впечатление, что суть самобытная безопасность — это единственная проблема АйТи на пути к нирване) и провёл победоносное тестирование modwsgi против fastcgi. Комьюнити же, судя по проведённому мною поиску, разрывается между mod_python и FastCGI. Причём, FastCGI обычно имеется ввиду тот, что идёт в поставке Django — flup. Являясь популярным хостингом Python-приложений, мы не смогли пройти мимо и решили внести свою лепту в эту священную войну.

    Я искренне считаю, что любая технология должна оптимально соотносить кошерность реализации, производительность, удобство использования и универсальность. Исходя из этого и будет описано каждое из представленных решений. Я подошёл к вопросу выбора субъективно, остановившись на веб-сервере apache как универсальном понятном всем диспетчере процессов. Из www.wsgi.org/wsgi/Servers я выбрал flup ( trac.saddi.com/flup ), python-fastcgi ( pypi.python.org/pypi/python-fastcgi ), и mod_wsgi ( www.modwsgi.org ). Заодно взял mod_python ( www.modpython.org ) — как наиболее популярный среди среднестатистического хостера способ запуска python.

    Ближе к телу


    image
    Я попытался создать идеальные условия для всех вариантов, нет перезагрузок после некоего количества запросов, всё сделано штатными простыми способами. Практически, происходит тестирование эффективности и производительности пути Apache->Паблишер->Приложение. Многие подобные тесты зачем-то тестируют ещё и производительность интерпретатора, но я затруднился объяснить себе зачем сравнивать один и тот же интерпретатор, а в случае разных — формализовать реализацию какой функциональности и почему требуется тестировать. Особенно хочу обратить внимание на то, что все технические тесты дают только сравнительную оценку производительности. Поэтому не делалось никакой специальной настройки и увеличения производительности. Чтобы избежать лишних разглагольствований о php — в тест включён и mod_php.

    Для всех демонизированных процессов выбраны условия — 2 предзапущенных процесса по 5 тредов. Кроме специального случая с flup. Все приложения тестируются утилитой ab 100000 (сто тысяч) запросов, 10 одновременно, плюс дополнительный тест mod_python на 10000 (десять тысяч) запросов. Тесты последовательно проводились на апаче с 5-ю, 30-ю и 100 предзапущенными процессами (MPM Prefork) для определения тенденций.

    Подопытный

    Двухпроцессорный Xeon E5335 2.00GHz, RAM 4Gb, SCSI винчестеры со SCSI-3 интерфейсом. Установлена FreeBSD 7.2-RELEASE amd64, Apache 2.2.11, php 5.2.10, python 2.5.4, mod_wsgi 3.0, mod_python 3.3.1, mod_fastcgi 2.4.6, python-fastcgi 1.1 и fcgi devkit 2.4.0, flup 1.0.2. Все тесты проводились локально на сервере, нагрузка никогда не выходила за 1.
    image
    image
    image

    flup

    Представляет собой WSGI-сервер с интерфейсом FastCGI. Является основным и единственным штатным способом запуска Django-приложения docs.djangoproject.com/en/dev/howto/deployment/fastcgi. Для тестов я использовал следующую программу:
    #!/usr/local/bin/python<br/> <br/>def my_wsgi_application(environ, start_response):<br/>        status = '200 OK'<br/>        output = 'Hello World!'<br/>        response_headers = [('Content-type', 'text/plain')]<br/>        start_response(status, response_headers)<br/>        return [output]<br/> <br/>application = my_wsgi_application<br/>from flup.server.fcgi import WSGIServer<br/>wsgi_opts = {'maxSpare': 5,'minSpare': 5,'maxThreads': 5}<br/>WSGIServer(application,**wsgi_opts).run() <br/>

    Такому способу запуска приложений присуще несколько трудностей — невозможность перезапуска приложения без перезапуска сервера, невозможность перезагрузки кода приложения без перезапуска или каких-то сторонних доработок, необходимость самостоятельно объявлять обработчик fastcgi и его параметры в приложении. Это верно и для python-fastcgi. Как видно из результатов, flup имеет некую насыщенность уже на тесте с 5-ю предзапущенными процессами апача. Так же, зафиксировал, что всё что flup не может обработать сразу, он выкидывает. Я получал до 40% ошибок запросов на тестах. Грусть и печаль вызывает этот тест, поскольку программисты по моей статистике редко смотрят как будут работать программы и для многих я открываю сейчас америку. Очень удивившись, я решил посмотреть поведение flup без строгого ограничения запущенных нитей и написал следующую программу, убрав лишние параметры:
    #!/usr/local/bin/python<br/> <br/>def my_wsgi_application(environ, start_response):<br/>        status = '200 OK'<br/>        output = 'Hello World!'<br/>        response_headers = [('Content-type', 'text/plain')]<br/>        start_response(status, response_headers)<br/>        return [output]<br/> <br/>application = my_wsgi_application<br/>from flup.server.fcgi import WSGIServer<br/>WSGIServer(application).run() <br/>

    Результат был ожидаем. Потерь нет, flup создаёт треды по мере надобности (следил за выводом ps), но как и следовало предполагать, производительность упала почти вдвое.
    Итак, передаю тебе пламенный привет, самый популярный на сегодняшний день способ запуска Django…

    modwsgi

    Представляет собой WSGI-сервер оформленный в виде модуля к Apache. Основной способ применения — в режиме демона. Т.е. когда веб-сервер является только посредником между создаваемыми резидентными программами и управлялкой ими. Является основным рекомендуемым способом запуска Django docs.djangoproject.com/en/dev/howto/deployment/modwsgi Ввиду использования с Apache'ем можно использовать всякие апачевские «штучки» вроде .htaccess и не так пугает системных администраторов. Этот же факт сильно пугает разработчиков, услышавших о nginx и считающих Apache злом во плоти. Программка, использованная мною для тестов, выглядит так:
    def my_wsgi_application(environ, start_response):<br/>        status = '200 OK'<br/>        output = 'Hello World!'<br/>        response_headers = [('Content-type', 'text/plain')]<br/>        start_response(status, response_headers)<br/>        return [output]<br/> <br/>application = my_wsgi_application <br/>

    Результаты тестирования показывают увеличение производительности с увеличением обработчиков Apache, т.е. отсутствие насыщенности. И явно производительнее flup.

    Хочется отметить некоторые особенности modwsgi. Во-первых, он имеет собственную настройку, сколько запросов обработать прежде чем перезагрузиться. Это позволяет ему эффективно бороться с утечками памяти. Я не сделал этой настройки в примерах (как и для других способов), ибо очевидно, что это немного уронит производительность. Во-вторых, он имеет уникальную, в отличии от остальных способов, настройку времени простоя, после чего он перегружается. Это позволяет не держать в памяти развёрнутое приложение или приложение с утекшей памятью в то время, когда оно не требуется. В-третьих, он автоматически перегружается при обновлении файла приложения. Т.е. при модификации программы, мы всегда уверены, что увидим новую версию. Никто из перечисленных способов не умеет ничего этого без специальных доработок. Ещё одной важной особенностью является вынос даже поминания способа запуска приложения из зоны ответственности приложения. Обратите внимание на пример — программа действительно имеет только WSGI-интерфейс и всё.

    python-fastcgi

    Представляет из себя… бинго! — WSGI_сервер, с интерфейсом FastCGI. На деле — обёртка вокруг стандартного C++ FastCGI. Программа выглядит так:
    #!/usr/local/bin/python<br/>import fastcgi<br/>def my_wsgi_application(environ, start_response):<br/>        status = '200 OK'<br/>        output = 'Hello World!'<br/>        response_headers = [('Content-type', 'text/plain')]<br/>        start_response(status, response_headers)<br/>        return [output]<br/> <br/>application = my_wsgi_application<br/>s = fastcgi.ThreadedWSGIServer(my_wsgi_application, workers=5)<br/>s.serve_forever() <br/>

    Результаты теста говорят сами за себя. С ростом обработчиков сервера растёт производительность. Очевидно, python-fastcgi — лидер наших тестов (привет, Locum). Вообще, после того как я в принципе победил подъём FastCGI посредством Apache, этот модуль вызвал меньше всего вопросов и нареканий. Естественно, он обладает всеми недостатками такого способа запуска — сложность настройки, зависимость сервера от приложения, отсутствие штатных инструментов перезагрузки (например, чтобы обновить программу), etc.

    mod_python

    Представляет собой модуль сервера Apache наподобии mod_php. Имеет несколько «зацепок», не имеет WSGI-интерфейса. Основной проблемой считается безопасность, поскольку без доработки исполняется от имени сервера. Правда, этим же недостатком болеет любой встроенный модуль, включая mod_php. Я написал следующую программку для тестирования:
    #!/usr/local/bin/python<br/> <br/>def index(req):<br/>        return "Hello World!\n" <br/>

    Неожиданно результаты оказались достаточно скромными. В процессе тестирования выяснилась ещё одна особенность. Вот результаты тестов на 10000 тысячах запросов:
    image
    Видно, что с увеличением числа обработчиков производительность… падает. Это объясняется тем, что при запуске сервера apache не «подсасывает» приложение, а делает это только по факту попадания запроса в один из обработчиков. Соответственно, чем больше я сделал обработчиков, тем больше запросов пришло «в первый раз». Совершенно очевидно, что при наличии 2-3 активных приложений, перегрузка будет достаточно частой. Выбирать ли способ запуска приложения, когда настраивать можно будет только целиком сервер — дело конечно ваше. Также, mod_python имеет проблемы обновления кода. Хотя у него есть соответствующая настройка, нам не удалось его заставить эффективно обновлять код приложения при изменении без перезагрузки всего сервера. На некоторых хостингах он работает без видимой проблемы обновления кода за счёт использования модуля diffpriv. Но возникает вторая проблема — приложение загружается сервером на КАЖДЫЙ запрос, что уже даже экстраполируя наши тесты даёт серьёзное падение производительности. И отдельный острый вопрос, конечно же — выбор «паблишеров» и работа с ними. Оказалось, что mod_python — самый подвал нашего рейтинга по сумме показателей.

    mod_php

    Для сравнения, я решил прогнать через тесты и php. Программка выглядит вполне очевидно:
    <?php echo("Hello, World!"); ?> <br/>

    Результаты очевидные, но воображение не поразили. При отсутствии лишней связи и монолитности самого php я ожидал множителя от 2 и выше.

    Резюме достаточно простое и очевидное. чем технология проще, тем она обычно производительнее. Лидер рейтинга в номинации производительности несомненно python-fastcgi, лидер в номинации удобства — modwsgi. Более того, modwsgi очевидно на сегодня представляет собой оптимальное решение по суммам характеристик, хотя не является ни самым производительным, ни самым безглючным.
    Метки:
    Поделиться публикацией
    Похожие публикации
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 91
    • +3
      сразу же хочется посмотреть на все конфиги всех частей тестовых систем.
      • 0
        У FastCGI значивая часть
        FastCgiServer /home/user/project -processes 2 -user user -group user
        У mod_wsgi
        WSGIDaemonProcess wsgi-test user=uwsgi group=user home=/home/user processes=2 threads=5 maximum-requests=0 inactivity-timeout=60 display-name=wsgi-test
        Какое место в конфигах ещё интересно? FastCGI — да, через suexec. Не принципиально для оценки.
      • 0
        и заодно вопрос — производилась ли какая-либо оптимизация тестовой ОС
        • 0
          Нет, там в начале написано. Я, кстати, не знаю что надо оптимизировать для «Hello, world» :) FreeBSD. Пустая. Только апач торчит и всё. Параметры даны. Но я ещё в начале написал — не знаю как это может кому-то помочь.
          • 0
            Ну теоретически имеет смысл соптимизировать систему по заветам Сысоева: www.opennet.ru/base/net/tune_freebsd.txt.html

            Хотя не думаю что на такой вот тестовой нагрузке это приведёт к смене расклада.
            • 0
              Вот и я так подумал. Смысл-то? Там же не сетевые сокеты.
        • +1
          nginx + wsgi не смотрели?
          • 0
            Что такое «nginx+wsgi»? nginx — это веб-сервер. wsgi — спецификация интерфейса. Что значит Ваш "+"?
            • +2
              Ночь, голова совершенно не тем забита =) Я про mod_wsgi для nginx хотел сказать.
              • НЛО прилетело и опубликовало эту надпись здесь
                • +1
                  Смотрел. У меня на dev сервере (Celeron 2,9GHz c 512 мозгами) c django+pgsql, 20 воркеров при запросе с далёкого сервера выдавали бешенные результаты: ~70 запросов/сек, против apache+mod_php который выдавал около 25 запросов/сек. Я бы мог понять разницу в 10%-30%, но не в 3 раза.
                  • +1
                    nginx является мультиплексором. Любая задержка внутри процесса превращает его в пень. А mod_wsgi под nginx предполагает только embedded режим. А держать кучу воркеров — а чем это тогда от апача отличается по сути?
                    • НЛО прилетело и опубликовало эту надпись здесь
                • 0
                  + означает, mod_wsgi для nginx. По моим тестам эта связка работает намного быстрее апачевского mod_wsgi. Жаль, что проект заброшен.
                  • +1
                    Ну вот смотрите — если у вас есть возможность держать для пользователя отдельный nginx с набором воркеров — почему бы не вывесить вебсервер напрямую. Например Cherrypy или тот же fapws?
                    • 0
                      Я реально советую посмотреть осмысленность того модуля.
                      • 0
                        Что сделать?
                        • 0
                          Объясните смысл. В чём смысл того модуля?
                  • +2
                    У него проблема есть. Если в приложении возникнет блокировка колом встанет весь сервер.
                    • 0
                      наблюдал подобные эффекты и в связке apache + mod_wsgi.
                      • 0
                        Там зависит от того какой у вас mpm используется.
                        • 0
                          Можно подробнее? Я пока решения своей проблемы не нашел и просто через каждые несколько миллионов запросов приходится перезапускать сервер.
                          • 0
                            У вас какой apache?
                            • 0
                              Apache/2.2.9 под Debian lenny
                              • +1
                                Если у вас установлен apache2-mpm-worker поставьте apache2-mpm-prefork. Учтите что если у вас им же статика отдается, то может возрасти нагрузка.
                                • 0
                                  Спасибо, буду изучать вопрос. Сервер рабочий, на нем не очень-то поэкспериментируешь, да и глюк случается довольно редко, поэтому попробую найти какое-то строгое обоснование происходящему.
                    • 0
                      У меня, кстати, вопрос. Немного холиварный.
                      При отсутствии лишней связи и монолитности самого php я ожидал множителя от 2 и выше.
                      Почему python тогда? Ну понимаю, пхп говно и прочее, но что физически мешает всей связке достигнуть такой же производительности, как mod_php?
                      • 0
                        Эммм. Производительности вывода hello world?
                        • 0
                          Тут ваще весь тест — производительность hello world, если че :)
                          ну т.е. производительность оверхеда :)
                          Почему у питона оверхед этот так значительно больше?
                          Тут ведь особенности, скажем, синтаксиса языка тут явно не причем.
                          • 0
                            Почему у питона оверхед этот так значительно больше?
                            Моя думать, что WSGI дает больший оверхед, чем mod_php. Вообще стоит сравнить mod_php с fastcgi php или cgi php тогда можно что-то сказать.
                            • 0
                              Оверхед в наличии дополнительной связи между сервером и непосредственно воркером приложения по протоколу fastcgi/внутреннему протоколу.
                              Мы хотели еще провести тест php в режиме fastcgi, но сборка php-fpm не самая тривиальная задача. Да и не было цели сверять php и python. Тест немного о другом.
                          • 0
                            Питон потому что он сам по себе и проще, и вообще более классически, да и более производительный. Так скажем. на нагруженных проектах он выдержит больше, но это всё уходит за рамки нашего исследования.
                            • 0
                              Спасибо. Именно такого ответа я и хотел. Типа:
                              1. Питон более интересный язык;
                              2. Питон более производительный на нагруженных проектах.
                          • +1
                            Хотелось-бы увидеть еще производительность на этом железе Fapws (Fast asynchronous python wsgi server) william-os4y.livejournal.com. Как вы на это смотрите?
                            • 0
                              и когена заодно если можно
                              • 0
                                Fapws требует свежей libev. Которую надо еще собрать.
                                К тому же fapws (по крайней мере, когда я его пробовал) блокирует треды, что отменяет возможность перезагрузки приложения по таймауту.
                                • 0
                                  Только что потестил, на hello world рещультат впечатляющий, на моем стареньком атлоне 4500 запросов.
                                  Но стоило только поставить таймаут на пару секунд на ответ внутрь кода, как выяснилось, что он не обрабатывает соединения параллельно, а все по очереди!
                                  То есть прийдет параллельно пара запросов и один их них будет ждать другого, а в реальной жизни не всегда hello world
                                  Я сильно не копался — взял примеры, возможно что-то там и можно подкрутить
                                  • 0
                                    Все верно. fapws не является многопоточным, а реализует событийную машину. Любая задержка в приложении — остальные ждут. Как, собственно и в nginx.
                                    • 0
                                      Отлично :(
                                      Только в нгинксе проще — он или сам отдал статику/кеш или передал дальше эстафету.
                                      А что тогда модет подойти под такую задачу, когда надо пара сотен параллельных процессов/потоков с довольно длительными задачами, но без апача, а желательно и сервер на питоне?
                                      Я пока немного разного пробовал, но пока что-то всё не то…
                                      • 0
                                        серверы, использующие событийную модель, как лицензия gpl: заражают ей все приложение. :)
                                        • +1
                                          В таком случае идеально подходит веб-сервер MochiWeb, но придется учить Erlang :)
                                          Есть даже примеры миллиона одновременных запросов с постоянным соединением (т.н. Comet-приложения)
                                          • 0
                                            спасибо, если надо, то и эрланг можно — лишь бы заработало :)
                                          • 0
                                            Если не хочется учить erlang, то можно еще посмотреть на python/twisted.
                                            • 0
                                              Я тоже так решил, только почему то там тоже выполнение идет последовательно, правда не углублялся еще.
                                        • 0
                                          вот что интересно. если приложение чисто вычислительное (рассчитывает координаты сферического коня в вакууме, или отдает «Hello, World!» :) ), то использование ниток или процессов производительности не прибавляет, а даже наоборот. процессор все равно один и лишние переключения контекста ни к чему. другая картина получается, когда приложение часть времени проводит в ожидании (синхронного ввода-вывода, результата sql запроса, или стоит таймаут на пару секунд :) ). в это время процессор не задействован, сервер может обрабатывать другие соединения. картина производительности будет иная.
                                          • 0
                                            нитки/процессы vs событийные.
                                            • 0
                                              А зачем? И так всё ясно ИМХО :)
                                      • +3
                                        off: слог донельзя напоминает машинный перевод: «уникально поправил», «отринул с безопасностью». можете пояснить что значат эти обороты? или материал действительно переводной?
                                        • 0
                                          Нет, статья своя, конечно. Вдаваясь в текст — джино, судя по всему, действительно «уникально» по их словам поправил апач, заставив его запускать процессы из под пользователя. Правда, метод этот уже известен более 6 лет и разработан Дмитрием Котеровым.
                                        • 0
                                          А как выглядит конфиг апача для тестирования flup?
                                          • +1
                                            вот любопытно. если разделить transfer rate (клобайт/сек) на request per seconds, то получим килобайт / запрос.
                                            1014,09	/ 3484,67	0,291
                                            754,55	/ 3140,87	0,240
                                            720,04	/ 3262,5	0,221
                                            654,98	/ 1202,8	0,545
                                            639,66	/ 2651,86	0,241
                                            171,23	/ 712,78	0,240
                                            

                                            интересно, что у «flup 2 процесса / 5 тредов» эта величина больше чем у других конфигураций в два с небольшим раза. он что, строчку «Hello World!» отдает в юникоде? =)
                                            • 0
                                              Забавно, да. Лишнего шпарит где-то. Посмотрю
                                            • 0
                                              у джанге есть prefork способ запуска fcgi, не только threaded. интересно, какие бы в этом случае были результаты.

                                              Ну и, я, конечно, понимаю что цели сравнивать nginx и апач не стояло, но если бы добавить в тестирование ещё и nginx + fcgi (prefork и threaded) то было бы гораздо, гораздо интереснее.

                                              • 0
                                                LA скорее всего зашкалит. Процессы таки. Посмотрю.
                                                А в чём формальный смысл сравнение такой связки? Ну будут те же оценочные результаты. Разница-то.
                                                • 0
                                                  ну, в сравнении nginx'а и апача, в основном, конечно, будет смысл.
                                                  • 0
                                                    OMG! Чего сравнения??? :))) nginx'а и apache'а? А в чём их сравнивать можно?
                                                    • 0
                                                      т.е. вы считаете что нет смысла сравнивать скорость и потребление ресурсов апача с mod_fastcgi и nginx'а?
                                                      • 0
                                                        В данной задаче нет. Более того, ни в какой другой тоже. Результат очевиден. Я там в начале написал про «комплексное решение».
                                                        • 0
                                                          а, понял.
                                                          • 0
                                                            А я не понял. Ну нет у вас задачи сравнивать apache и nginx (читать «вы все равно не поставите nginx), но другим то результаты интересны, почему бы и не сравнить.
                                                            • 0
                                                              Ммм… нет, просто нет смысла сравнивать автобус и фуру. Кстати, вот например в автобусах ликенского автозавода образца так года 2000-го стоит камазовский движок. Можно даже технически попробовать сравнить.
                                                              Формализуйте мне тесты сравнения. Какой функционал с каким и почему.
                                                • +1
                                                  > Являясь популярным хостингом Python-приложений хостингом Python-приложений
                                                  я по два раза не повторяю, не повторяю :))
                                                  • 0
                                                    Опс… Спасибо, поправил :))
                                                  • 0
                                                    Хотелось бы еще увидеть сравнение с Passenger в режиме wsgi.
                                                    • 0
                                                      Воопрос интресный. Я тут выложу как я тесты делал. Предлагаю взглянуть.

                                                      P.S. Хотя, ответ ИМХО очевиден…
                                                    • 0
                                                      Жесть. как Вы думаетет будет ли зазница между запуском апача, и например другово сервера.
                                                      • 0
                                                        Будет. Апач сам по себе монстр. Но в этом тесте тестировалась скорость именно связки апач->приложение.
                                                        • 0
                                                          Не понял вопроса. Разница в чём? В запуске? Если он не похож на апач — будет. В оценке сравнительной производительности? Скорее всего нет, если я нигде не ошибся. В цифрах? Не смотрите на них. Будет.
                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                          • 0
                                                            mod_worker с 1 тредом == mod_prefork.
                                                          • +2
                                                            идиотский вопроса на всякий случай

                                                            1) отключали ли mod_php и прочие ненужные mod_* при тестировании с питоном?

                                                            а вообще что то у вас не то, ибо слишком медленно для hello world! Я когда-то тоже много экспериментировал (результаты — ниже) и у меня на AMD 3800+ (1 ядро) выдавало более 2000req/s, а на Intel 6700 quad core — почти 9000 при 4х «горячих» форках через mod_wsgi (естественно, daemon mode).

                                                            в целом если не трогать php (который тут в шутку похоже, или чтоб не спрашивали «а где же наш любимый пэхэпэ?!», то основные (юзабельные для продашна) на мой взгляд схемы это:
                                                            1) apache 2.2 / worker + mod_wsgi
                                                            2) apache 2.2 / worker + python-fastcgi
                                                            3) lighttpd/whatever + python-fastcgi

                                                            при этом я на апача очень долго сидел после того как запарившись как-то сильно ковырялся с компиляцией, все модули — в статику, большую часть дефолтных модулей вообще нахрен выкидывал за ненадобностью. Но 1 апачевский «упс» при этом все равно остаётся — в worker ему нужно выделить виртуальную память для всех возможных тредов. А в случае vps где иногда нет swap — это означает что сжирать он будет нереально много (правда, это значение при повышении нагрузки никогда не увеличится уже, что тоже удобно).

                                                            lighttpd/whatever в этом плане веселей, ибо у них футпринт в памяти просто мизерный в сравнении с апачем. У конкретно lighttpd ещё и довольно стабильный загрузчик/менеджер fastcgi приложений.

                                                            самое же главное — что выбирать между этими схемами надо именно из расчета «что удобнее», а никак не «что быстрее». Ибо в любом приложении отличном от Hello world разница становится абсолютно незаметной и несущественной. Главное лишь связку грамотно настроить. А вот тут начинаются грабли, связанные с тем, что грамотно настроить апач на его макс. производительность несоизмеримо сложнее чем вообще не настраивать тот же lighttpd =). Да и даже если запарится и долго тестить/экспериментировать с разными mod_prefork/mod_worker и их параметрами — результат не получится сделать быстрее lighttpd.

                                                            по поводу mod_wsgi vs python-fastcgi/mod_fastcgi хочется сказать отдельно. Mod_wsgi безумно логичен, но не лишён недостатков. Главный из них — это всё же наличие интерпретатора питона прямо в самом mod_wsgi (и, как следствие, потом в апаче, хотя это уже пофик). А это значит что засовывается он туда при компилляции. А это значит что воткнуть туда «левый» питон (не тот что основной на сервере) архи проблематично — потом ещё запускать весь апач с тюнеными LD_LIBRARY_PATH и LD_RUNTIME_PATH… брррр. Ну и последний гвоздик — 2 разных mod_wsgi под одним апачем, увы, совсем никак. Из плюсов апача пока ещё есть (и, вероятно, ещё побудет некоторое время =)) — настраиваемость и уйма возможно нужных других модулей… Есть ещё маленький бонус — писать свои mod_* в апаче используя восхитительную arp (apache runtime library) — одно удовольствие.
                                                            • +2
                                                              да, и выше видел про «колом встающий апач с mod_worker и mod_wsgi при слипах».

                                                              обращу внимания что mpm тут ваще не при чем. Апач запускает либо 2-3 форка и потом запускается управляющий форк mod_wsgi которому передаются все запросы нужные (чего там mod_wsgi уже запустит апача не касается, он все их сваливать в 1 форк будет все равно). Либо тоже самое, тока внутри форков апача ещё и потоки порождаются (и все равно они все будут стучаться в 1 форк mod_wsgi).

                                                              Далее когда идут запросы, они идут на mod_wsgi в многопоточном режиме, а он уже перебрасывает их по схеме как настроен. Если например daemon mode с 1 приложением, 2 форками и 20 потоками в каждом, то одновременно может сожрать 40 обрабатывающихся внутри питона запросов (если канеш сам апач столько сможет одновременно сожрать — тут уж настройка mpm).

                                                              Так вот и коварность mod_prefork состоит в том, что пока запрос обрабатывается внутри mod_wsgi (в котором может быть например 1 процесс со 100 тредами прямо внутри питона), ему один хрен нужен 1 форк самого апача на КАЖДЫЙ запрос. Т.е. ему надо будет разогнать 100 форков (предполагаю, в разогретом состоянии 100 форков никто не держит? =)). И не дай бог в апаче стоит mod_php, ибо размер форков апача в таком случае будет апокалептичным (ну ладно-ладно, только если mod_php ещё и в статике запихнут =)).

                                                              При mod_worker 1 форк апача может обрабатывать энное кол-во одновременных запросов через потоки внутри самого форка. А так как апач в случае mod_wsgi фактически тупо перебрасывает последнему запросы — это как раз то что нужно, и worker гораздо практичнее prefork.

                                                              prefork, как правило, рушит сервер очень быстро, как только чуть чуть начинает хаваться своп — дальнейшее порождение форков убивает систему совсем начисто (если макс. лимит выше чем макс. памяти / размер форка, но тут уж надо сильно аккуратно настраивать prefork). Worker же начнёт убивать в таком случае сервер медленно, ибо каждый новый форк сможет обработать, например, ещё 100 соединений, а там уже лимит самого приложения вашего (т.е. настройка mod_wsgi) должен слать куда-подальше — в итоге вываливая всем подряд http 500.

                                                              Сразу скажу — не спорьте, если не верите — у Грэма Дамплтона (автор mod_python и mod_wsgi) в блоге есть афигенный трактат по этому поводу. В общем-то я просто по-русски это всё описал, но у него — подробнее =).
                                                              • +2
                                                                ну и в довесок — остаточный страх mod_worker остался после сумасшедших глюков mod_php и worker mpm года 3-4 назад. В то время php хоть сам и был вроде как thread-safe, но вот какие-то из его расширений — не были, а т.к. в случае worker mpm есть 1 процесс внутри которого 25 (ну или скока там у вас) тредов и в это же процессе 1 пхп обрабатывает запросы этих тредов — крыша у не thread-safe расширений (и у всего приложения в целом) откровенно протекала.

                                                                Это же касается и других не thread-safe mod_* апача и сишных расширений питона (благо, таких по пальцам пересчитать).
                                                                • 0
                                                                  Я предупредил, что может быть все плохо. А mod_wsgi получается работает довольно похоже с mod_fastcgi, только в сторону pyhton. Я думал он как нибудь все же по-другому, если там так, то замена mpm ничего не даст.
                                                                  • 0
                                                                    Почему замена mpm ничего не даст?
                                                                    • 0
                                                                      Читаем выше. Замена на mpm_preforker не даст профита в виде независания mod_wsgi.
                                                                      • 0
                                                                        Какое такое зависание mod_wsgi? Ты о чём, коллега? :)
                                                                          • 0
                                                                            Нет, ты по русски объясни. Там как раз написано что поможет. Не с зависанием правда, но поможет. А ты о чём? Давай, по пунктам.
                                                                            • 0
                                                                              Цитирую:
                                                                              Апач запускает либо 2-3 форка и потом запускается управляющий форк mod_wsgi которому передаются все запросы нужные (чего там mod_wsgi уже запустит апача не касается, он все их сваливать в 1 форк будет все равно). Либо тоже самое, тока внутри форков апача ещё и
                                                                              потоки порождаются (и все равно они все будут стучаться в 1 форк mod_wsgi).


                                                                              Сугубо говоря в независимости от mpm есть управляющий форк. Если он вешается, то всему приходит копец. Кстати у fastcgi есть такой же управляющий форк.
                                                                              • 0
                                                                                И как часто у тебя он вешается? Через 5 дней будет год коммерческого использования. Ни разу не повис.
                                                                                • 0
                                                                                  А кто сказал что у меня? :) Это вон у товарищей выше у них и узнавай.
                                                                                  • 0
                                                                                    Где? С nginx? Ну логично. Ты читать умеешь? :)) Там embeded mode
                                                              • 0
                                                                Не отключали. ППКС под всем. mpm-worker попробую действительно
                                                                • 0
                                                                  я вот сейчас минималистичную статическую сборку апача только гентой делаю (совсем разленился… =)), благо это мегаудобно нынче. Прирост это может дать весьма внушительный (ну может процентов 5 — сильно зависит от захломлённости текущего варианта =)), особенно в prefork режиме, если форки новые запускаются. Ну и, конечно, афигенно ощутимо меньше кушает памяти.

                                                                  сейчас ещё cherokee пополз вперёд. Я его даже и не щупал ещё толком, совсем не до этого. Но согласно www.cherokee-project.com/benchmarks.html — весьма многообещающая штука (не хило ли, 2х по сравнению с апачем — уже не шутки). Особенно учитывая что lighttpd заглох и остыл… а на холодную больше не заводится =)), nginx — промолчу… его ниша — бэкпрокси и точка. Разные fapws — для песочниц и игрушек да и только пока что.
                                                                  • +1
                                                                    Cherokee стоит попробовать. У нас сейчас все проекты на Django работают на связке Cherokee + scgi. Очень быстро, надежно и удобно.
                                                                    • 0
                                                                      Да, мы смотрим на него. Но… Но да, интересно.
                                                                  • 0
                                                                    ещё кстати можно mod_scgi попробовать… Тоже руки никак не доходили. По смыслу scgi мне очень нравится — спецификация малюююсенькая, как сильно упрощённый fastcgi. А скорость — точно такая же.

                                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.