⬆️ ⬇️

StaticGenerator Pro

Jared Kuolt created a small caching script for Django. Everyone is remarkable: and simplicity and size.



But the StaticGenerator script and the nginx config provided by Jared have flaws:

1) relevant only for sites without registration;

2) work with links of simple type only;

3) generation only when changing / adding content and / or comments.



I corrected these shortcomings, added something interesting to the script, and it turned out StaticGenerator Pro .



Its additional features:
  1. Caching for anonymous visitors only

    Requests from registered users, for which the appearance of the page may be different, are always forwarded directly to Django, without caching, which in this case does not make sense. Thus, StaticGenerator Pro is useful primarily for anonymus (and they are usually more than 99%).

    ')

    User definition occurs not only in the script, but also in nginx-e (it is based on the presence of the sessionid in cookies).

    This required changes to the generator script and the nginx config.



    A piece of the modified nginx config to distinguish anonymous users from authorized users (instead of an Apache backend, I have Django working via 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;

    }

    }

    }

    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;

    }

    }

    }



    Another nice feature:

    in the nginx logs, you can see whether the page was returned from the cache or via django. It is enough to add $ django to the log format.

    For example:

    log_format main '$remote_addr [$time_local] "$request" '

    '$status $bytes_sent $body_bytes_sent $gzip_ratio '

    '$django "$http_referer" "$http_user_agent"';



    In the logs

    0 - page from file (cache)

    1 - page through fcgi from django

  2. Middleware , which generates static files during the first access, all subsequent ones are taken from the cache.

    Static files are created only with a positive response (code 200) and a GET type request.



    To install you need to place the generatorpro.py in the project folder

    and add to MIDDLEWARE_CLASSES in settings.py 'generator.ResponseStaticGenerator'.

    Do not forget to prescribe the path to the folder www.

    from os import path

    WEB_ROOT = path.realpath("www")



    So you can place the cache in the project directory.

  3. Work with links with arguments in line , of the form www.alrond.com/?test=1

    Each unique option is cached separately.

  4. In settings.py it is possible to set the beginning of paths that are excluded from caching :

    STATIC_GENERATOR_EXCLUDED = (

    '/comments/postfree',

    '/rating',

    '/rss',

    '/admin',

    )


    Thus, for example, all paths starting with / comments / postfree, / rating, / rss, / admin are excluded.



    Of course, you need to take into account for your applications that sometimes unique data can be shown to anonymous users, in which case these paths can also be simply excluded.

  5. Clever cache removal

    Removing a particular path leads to the removal of all variants with arguments (of course, before the first conversion).



    For example, deleting http://www.alrond.com/en/index.html removes http://www.alrond.com/en/index.html?test=1 and http://www.alrond.com/ en / index.html? tag = django & sort = desc
  6. The possibility of exclusion from the cache in the controller views

    It is enough to simply insert response ['DisableStaticGenerator'] = 1 before any response handler.
The script works great: my blog, for example, capable of generating 14.2 pages per second on my home computer, generates 7500 pages per second with a script. It is 530 times faster!



Download StaticGenerator Pro here . The only difference is in the added class ResponseStaticGenerator and the slightly modified delete_from_path function



Original article: www.alrond.com/ru/2008/feb/23/static-generator-pro

Source: https://habr.com/ru/post/20922/



All Articles