Несколько механизмов хранения для носителей django: предпочитайте локальный, откат к CDN

У меня есть проект django/mezzanine/django-cumulus, который использует CDN облачных файлов в стойке для хранения мультимедиа. Я хотел бы автоматически обслуживать все статические файлы из локального MEDIA_ROOT, если они существуют, и только возвращаться к URL-адресу CDN, если их нет.

Один из возможных подходов — управлять откатом на уровне шаблона с помощью тегов. Однако я бы предпочел не переопределять все шаблоны администратора (например) только для этого.

Есть ли способ изменить обработку всех носителей, чтобы сначала использовать один механизм хранения и переключаться на второй при ошибке?


person evilchili    schedule 27.02.2014    source источник


Ответы (2)


Лучший способ, чтобы это работало, - это иметь другой веб-сервер, обслуживающий все ваши медиа (я использовал nginx). Затем вы настраиваете балансировщик нагрузки для обнаружения сбоя и перенаправляете все запросы в CDN в случае сбоя. Одна вещь, которую вам, возможно, придется выяснить, — это путь к изображению (используйте HAProxy, чтобы переписать URL-адрес запроса, если вам нужно).

person Anup    schedule 27.02.2014
comment
Интересная идея. Я думаю, что балансировщик нагрузки излишен; возможно, будет достаточно поймать 404 и перенаправить их. Это можно сделать на уровне веб-сервера или с помощью специального обработчика 404 в приложении django? Мне придется поэкспериментировать. - person evilchili; 28.02.2014
comment
Да, на мгновение перед тем, как опубликовать это, я подумал, что было бы неплохо взломать core.context_processors.static. Но я действительно не уверен, что это правильный способ сделать это. нам нужно проверить перед возвратом {'STATIC_URL': settings.STATIC_URL}. Но это будет происходить при каждом запросе, и это определенно повлияет на время отклика приложения, поэтому я чувствовал, что его там быть не должно. Дайте нам знать, как это происходит. - person Anup; 28.02.2014

Основываясь на предложении Анупа, я обнаружил, что этот фрагмент конфигурации nginx прекрасно справляется с условием 404:

location /static/ {
    root            /path/to/static_root;
    # ...
    error_page 404 =  @cdn;
}

location @cdn {
    # cdn_cname.example.com is an alias for deadbeef012345.r99.cf5.rackcdn.com
    rewrite ^/(.*)$ http://cdn_cname.example.com/$1 last;
}

Это корректно перенаправит любой запрос на /static/URI, который возвращает 404 на локальном сервере, в CDN. Однако django-cumulus по-прежнему отображает ссылки на статические файлы через CDN. Чтобы это исправить, я добавил в блок CUMULUS файла settings.py следующее:

CUMULUS {
    # ...
    'CONTAINER_URI': 'http://example.com/static',
}

Теперь ссылки django-cumulus используют статический URI локального сервера, который будет соответствовать приведенной выше конфигурации nginx, и перенаправлять на CDN только при необходимости. Ура!

person evilchili    schedule 28.02.2014
comment
Ах... Я пропустил nginx 404. Выглядит аккуратно. - person Anup; 28.02.2014