slav0nic's blog

Заметки о python, linux и других занимательных вещах

Альтернативные WSGI сервера для Django

Столкнулся с проблемой, после обновления джанги перестал корректно работать сервер scgi-flup + lighttpd. Причина банально проста, при POST-запросе на / получаем /, то есть вылазит SCRIPT_NAME :|. По совету на pythonua@c.j.r вылечил установкой параметра FORCE_SCRIPT_NAME = ''. Но flatpages отвалились, тк они по прежнему искали /about %) Желание откатываться на django 0.97 оставил, поэтому стал искать альтернативный метод решения проблемы. Как показали тесты, python-scgi (набор библиотек от автора протокола) оказался быстрее чем flup (процентов на 30-40%, проверял на хеллоуворлде) к тому же последний неплохо течёт при большой нагрузке, но прикрутить его к django нет возможности (ибо не WSGI, а всякие гейты scgi-WSGI типа SWAP и тп являются мёртвыми проектами и неактуальными, да и врядли положительно скажутся на скорости).

WSGI решения

Сначала попробовал CherryPy, всё легко запускается, довольно быстро работает, но хотел чего-то большего ;) С подачи piranha глянул на FAPWS2 (Fast Asynchronous Python WebServer). Штука довольно интересная, использует libevent и основная часть кода написана на С, вечером нам всё таки удалось запустить проект на django 1.0. Из плюсов:

  • использует мало памяти (~ на 5мб меньше чем cherrypy)
  • написан на С
  • поддержка WSGI

Из минусов:

  • сомнительно стабильно %)
  • мало наворотов
  • проблемы с документацией

Одной из самый больших проблем оказалось отсутствие поля REMOTE_ADDR в запросе, из-за которого джанга местами валилась, хотя это можно легко исправить, но не факт что с остальным всё хорошо ;)

2й выбор пал на Cogen - "Coroutines and crossplatform asynchronous networking in python using enhanced generators from python 2.5" как описал это автор. Грубо говоря, это что-то вроде mini-twisted (надеюсь этой фразой я не спалил своё дилетанство в данном вопросе =) ) Так вот он, кроме всего, содержит в себе WSGI - сервер + работает через py-epoll. Для wsgi используется скрипт взятый из cherry, но доработанный под фреймворк (если это можно так назвать).

Теперь о вкусном=) По адресу http://code.google.com/p/cogen/wiki/WsgiServerBenchmark расположены бенчмарки, да, местами Twisted-Web2 выигрывает в скорости, но лично у меня нет желания юзать сию махину для данной цели, да и думаю там есть чему течь ;) Cogen также поддерживает middleware (смотреть cogen.web.async, хотя на WSGI мидлеты они не сильно похожи В] )

Запуска Django на Cogen

После запуска порадовала скорость, даже при 500 конкурирующих запросах (да, мало кому нужна такая нагрузка, но ради академического интереса пригодится) приложение не падало, ни одого failed request, при этом запросы обрабатывались равномерно (примерно за однин временной диапазон) %) В общем "ни единого разрыва" :p. Утечки памяти не были обнаружены, в то время как флуп при такой нагрузке отвечал на 25% запросов ошибкой. Из недостатков: как я понял у многих wsgi серверов проблемы с обработкой wsgi.input (хз в чём сложность, но в cogen и ещё одном сервере "из коробки" этого нет) и как поведёт себя cogen например при загрузке файла, я сказать не могу ибо не тестил, но сию проблему решил по простому (по дефолту от POST запросов джанга валится в трейсбек, тк wsgi.input = None). Скрипт для запуска Django:

#!/usr/bin/env python2.5
import sys
import os
import os.path
from cogen.web import wsgi
from cogen.web.async import sync_input
from cogen.common import *
if not os.path.dirname(__file__) in sys.path[:1]:
    sys.path.insert(0, os.path.dirname(__file__))
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

from django.core.handlers.wsgi import WSGIHandler
application = WSGIHandler()
m = Scheduler(default_priority=priority.LAST, default_timeout=15)
server = wsgi.WSGIServer(
           ('localhost', 9000),
            sync_input(application), #!!! load middleware for wsgi.input
            m,
            server_name='localhost')
m.add(server.serve)
try:
    m.run()
except (KeyboardInterrupt, SystemExit):
    pass

ЗЫ: easy_install cogen Проект довольно интересный, недостатков пока что не выявил. На сайте имеется документация и примеры скриптов, да и основная часть написана на python, разобраться не проблема. Возможно попробую использовать его + lighttpd c mod_proxy на боевом сервере. Написал заметку ради твика скрипта для обработки wsgi.input %))

bsdemon post on 2008-07-30 00:05:07
Интересно, а как тестировали? И что можно для production использовать?
slav0nic post on 2008-07-30 00:17:22
скорость? через ab (в поиске утечек и тп) ну его ещё 2 товарища с pythonua@c.j.r гоняли, проблем вроде не было, но о продакшине имхо рано говорить, на днях запущу, посмотрим.
wiz post on 2008-08-02 00:33:50
Ну так что, течёт коген или нет?
slav0nic post on 2008-08-02 00:50:52
за 3 дня не заметил, при этом периодически гонял ab, rss 19656 как было так и осталось
slav0nic post on 2008-08-03 01:03:10
блин словил IOError: [Errno 5] Input/output error =(( при жирном посте + посты иногда подтуплвиают=\

web.py