Jared Kuolt создал небольшой скрипт кэширования для Django. Всем замечателен: и простотой и размером.
Но у скрипта StaticGenerator и nginx-конфига, приведенного Jared-ом, есть недостатки:
1) актуально только для сайтов без регистрации;
2) работа с ссылками только простого вида;
3) генерация только при изменении/добавлении контента и/или комментариев.
Я исправил эти недочеты, добавил кое-что интересное в скрипт, и получился StaticGenerator Pro.
Его дополнительные возможности:
Скачать StaticGenerator Pro можно здесь. Отличие файла только в добавленном классе ResponseStaticGenerator и немного измененной функции delete_from_path
Оригинал статьи: www.alrond.com/ru/2008/feb/23/static-generator-pro
Но у скрипта StaticGenerator и nginx-конфига, приведенного Jared-ом, есть недостатки:
1) актуально только для сайтов без регистрации;
2) работа с ссылками только простого вида;
3) генерация только при изменении/добавлении контента и/или комментариев.
Я исправил эти недочеты, добавил кое-что интересное в скрипт, и получился StaticGenerator Pro.
Его дополнительные возможности:
- Кеширование только для анонимных посетителей
Запросы зарегистрированных пользователей, для которых вид страницы может отличаться, перенаправляются всегда напрямую к Django, без кэширования, которое в этом случая не имеет смысла. Таким образом, StaticGenerator Pro полезен прежде всего для анонимусов (а их обычно больше 99%).
Определение пользователя происходит не только в скрипте, но и в nginx-e (оно основано на присутствии sessionid в кукисах).
Для этого потребовалось внести изменения в скрипт генератора и в конфиг nginx-а.
Кусок измененного конфига nginx, чтобы отличать анонимов от авторизованних пользователей (вместо бекенда Apache у меня Django работает через fcgi):http {
# [here must be all standard parameters]
server {
server_name example.com;
listen 80;
root /home/mydjangoproject/www;
# изначально направляем всех к django
set $django 1;
# редирект неправильно реагирует на знак вопроса,
# поэтому необходима промежуточная переменная
if ($is_args = "?") {
set $args_old ?$args;
}
if ($is_args = "") {
set $args_old "";
}
# очень важно, иначе неправильно будут отдаваться
# файлы с аргументами в имени
default_type text/html;
location / {
if (-f $request_filename/index.html$args_old) {
set $django 0;
}
# определяем авторизированного пользователя
if ($http_cookie ~* "sessionid=([^;]+)(?:;|$)" ) {
set $django 1;
}
# отдаем кэш
if ($django = 0) {
rewrite (.*) $1/index.html$args_old break;
}
# перенаправление к django
if ($django) {
fastcgi_pass unix:/home/mydjangoproject/dj.sock;
break;
}
index index.html;
include conf/fastcgi.conf;
access_log logs/project.log main;
}
}
}
Еще приятная фича:
в логах nginx-а можно видеть, была страница отдана из кэша или через django. Достаточно в формат лога добавить $django.
Например, так:
log_format main '$remote_addr [$time_local] "$request" '
'$status $bytes_sent $body_bytes_sent $gzip_ratio '
'$django "$http_referer" "$http_user_agent"';
В логах
0 — страница из файла (кэш)
1 — страница через fcgi от django
- Middleware, которое генерирует статичные файлы при первом обращении, все последующие берутся из кэша.
Статичные файлы создаются только при положительном ответе (код 200) и запросе типа GET.
Для установки надо разместить generatorpro.py в папку проекта
и добавить в MIDDLEWARE_CLASSES в settings.py 'generator.ResponseStaticGenerator'.
Не забудьте там же прописать путь к папке www.
from os import path
WEB_ROOT = path.realpath("www")
Так можно разместить кэш в директории проекта.
- Работа с ссылками с аргументами в строке, вида www.alrond.com/?test=1
Каждый уникальный вариант кэшируется отдельно
- В settings.py возможно задать начало путей, которые исключаются из кеширования:
STATIC_GENERATOR_EXCLUDED = (
'/comments/postfree',
'/rating',
'/rss',
'/admin',
)
Таким образом, например, исключаются все пути, начинающиеся с /comments/postfree, /rating, /rss, /admin.
Конечно, надо учитывать для ваших приложений, что иногда уникальные данные могут показываться и анонимным пользователям, в таком случае эти пути тоже можно просто исключать.
- «Умное» удаление из кэша
Удаление определенного пути ведет к удалению всех вариантов с аргументами (естественно до первого обращения).
Например, удаляя http://www.alrond.com/en/index.html, удаляются http://www.alrond.com/en/index.html?test=1 и http://www.alrond.com/en/index.html?tag=django&sort=desc - Возможность исключения из кэша в контроллере views
Достаточно в любом обработчике просто перед return response вставить response['DisableStaticGenerator'] = 1
Скачать StaticGenerator Pro можно здесь. Отличие файла только в добавленном классе ResponseStaticGenerator и немного измененной функции delete_from_path
Оригинал статьи: www.alrond.com/ru/2008/feb/23/static-generator-pro