Хобрук: Ваш путь к мастерству в программировании

кеш-бэкэнд работает на devserver, но не на mod_wsgi

Я использую пользовательский бэкенд кеша, чтобы обернуть встроенные бэкенды кеша, чтобы я мог добавить текущий site_id ко всем cache_keys (это полезно для многосайтовой функциональности с одним экземпляром memcached)

к сожалению, он отлично работает на встроенном сервере разработки django, но выдает неприятную ошибку, когда я пытаюсь запустить его на живом сервере с mod_wsgi.

Вот трассировка из моего журнала ошибок:

[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] mod_wsgi (pid=22933): Exception occurred processing WSGI script '/home/jiaaro/webapps/op_wsgi/myProject/deploy/myProject.wsgi'.
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] Traceback (most recent call last):
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]   File "/home/jiaaro/webapps/op_wsgi/lib/python2.5/django/core/handlers/wsgi.py", line 230, in __call__
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]     self.load_middleware()
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]   File "/home/jiaaro/webapps/op_wsgi/lib/python2.5/django/core/handlers/base.py", line 40, in load_middleware
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]     mod = import_module(mw_module)
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]   File "/home/jiaaro/webapps/op_wsgi/lib/python2.5/django/utils/importlib.py", line 35, in import_module
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]     __import__(name)
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]   File "/home/jiaaro/webapps/op_wsgi/myProject/apps/site_settings/__init__.py", line 6, in <module>
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]     import cache_wrapper
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]   File "/home/jiaaro/webapps/op_wsgi/myProject/apps/site_settings/cache_wrapper.py", line 4, in <module>
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]     from django.core.cache.backends.base import BaseCache
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]   File "/home/jiaaro/webapps/op_wsgi/lib/python2.5/django/core/cache/__init__.py", line 73, in <module>
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]     cache = get_cache(settings.CACHE_BACKEND)
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]   File "/home/jiaaro/webapps/op_wsgi/lib/python2.5/django/core/cache/__init__.py", line 68, in get_cache
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1]     return getattr(module, 'CacheClass')(host, params)
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] AttributeError: 'module' object has no attribute 'CacheClass'

если я запускаю devserver на той же машине (живой сервер), он работает нормально... Я могу сделать это без проблем:

$ cd /home/jiaaro/webapps/op_wsgi/myProject
$ python2.5 manage.py runserver

и в отдельном сеансе ssh...

$ wget 127.0.0.1:8000

Страницы обслуживаются правильно, с использованием memcached и активной базы данных. Есть ли что-то другое в том, как mod_wsgi импортирует модули, о чем мне следует знать?

может быть, что-то об однопроцессном, однопоточном характере сервера разработки?

Я боролся с этим в течение нескольких дней, любая помощь будет оценена

Дополнительная информация:

  • Виртуальный хостинг Webfaction (centos)
  • Апач 2
  • Питон 2.5
  • Джанго 1.1.1
  • mod_wsgi 2.5
  • MySQL 5.0

Дополнительные сведения: - Я установил кеш-бэкенд (и он работает, поскольку вы можете видеть, что он импортирует правильный модуль в трассировке) - В модуле есть класс с именем «CacheClass»:

site_settings/cache_wrapper.py:

from django.conf import settings
CACHE_BACKEND = getattr(settings, 'CUSTOM_CACHE_BACKEND')

from django.core.cache.backends.base import BaseCache

class CacheClass(BaseCache):
    from decorators import accept_site

    def __init__(self, *args):
        from django.core.cache import get_cache
        self.WRAPPED_CACHE = get_cache(CACHE_BACKEND)

    @accept_site
    def add(self, site, key, *args):
        return self.WRAPPED_CACHE.add(self._key(site, key),*args)

    @accept_site
    def get(self, site, key, *args):
        return self.WRAPPED_CACHE.get(self._key(site, key),*args)

    ... (all the rest of the wrapped methods)

    def _key(self, site, key):
        from exceptions import NoCurrentSite
        if not site:
            raise NoCurrentSite
        return "%s|%s" % (site.id, key)

Декоратор accept_site работает в сочетании с некоторым промежуточным программным обеспечением для определения текущего сайта. Они здесь:

декораторы.ру:

def accept_site(fn):
    def decorator(self, *args, **kwargs):
        site = kwargs.get('site', None)
        try: 
            del kwargs['site']
        except KeyError: 
            pass

        from .middleware import get_current_site
        site = site or get_current_site()

        if not site:
            raise NoCurrentSite("The current site is not available via thread locals, please specify a site with the 'site' keyword argument")

        return fn(self, site, *args, **kwargs)

    return decorator

и промежуточное ПО.py

try:
    from threading import local
except ImportError:
    from django.utils._threading_local import local

from django.conf import settings
from django.contrib.sites.models import Site

DEFAULT_SITE_ID = 1

_thread_locals = local()
def get_current_site():
    return getattr(_thread_locals, 'site', None)

def set_current_site(site):
    setattr(_thread_locals, 'site', site)

class SiteSettings(object):
    """Middleware that gets various objects from the
    request object and saves them in thread local storage."""
    def process_request(self, request):
        if settings.DEBUG:
            site_id = request.GET.get('site_id', DEFAULT_SITE_ID)
        else:
            site_id = DEFAULT_SITE_ID

        current_site_domain = request.META["HTTP_HOST"]
        try:
            current_site = Site.objects.get(domain__iexact=current_site_domain())
        except:
            current_site = Site.objects.get(id=site_id)
        set_current_site(current_site)

Все это работает с использованием devserver, с теми же настройками, что и сервер wsgi, и настроенным с тем же путем python (насколько я вижу)

На данный момент я надеюсь, что где-то создал цикл импорта (хотя это не имеет смысла, поскольку это происходит только на сервере разработки)

изменить: я нашел список различий между devserver и apache в документах django, в которых говорится:

Devserver добавляет установленные приложения в sys.path, а Apache — нет.

Может, это как-то связано?


Ответы:


1

Вы установили CACHE_BACKEND в файле settings.py? Когда DEBUG=True, это не проблема, так как я считаю, что установлен фиктивный бэкэнд, но в продакшене вам нужно будет установить это значение, предположительно, даже если вы пишете свой собственный бэкенд.

кэшировать внутреннюю документацию

Если это установлено, но у вас все еще есть проблемы, попробуйте переключиться на фиктивный модуль кеша или модуль локальной памяти (даже если это не очень хорошая производственная установка), чтобы увидеть, работают ли они, и если они работают, вы можете пропустить пакет в пути python вашего WSGI, например python-memcached

17.02.2010
  • Я установил бэкенд кеша - на самом деле... мой пользовательский бэкенд кеша ИСПОЛЬЗУЕТСЯ для работы, прежде чем я рефакторинг его в другой модуль 17.02.2010

  • 2

    Корень проблемы был sys.path. Я должен был убедиться, что настроенный mod_wsgi имеет тот же sys.path, что и сервер разработки, и что не осталось лишних копий пакетов в местах, которым они не принадлежат (из-за рефакторинга, который не был применен на сервер через систему контроля версий как-нибудь)

    30.03.2010
    Новые материалы

    Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
    каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

    Как настроить Selenium в проекте Angular
    Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..