簡體   English   中英

緩存后端在devserver上有效,但在mod_wsgi上無效

[英]cache backend works on devserver but not mod_wsgi

我正在使用自定義緩存后端來包裝內置緩存后端,以便可以將當前site_id添加到所有cache_keys中(這對於具有單個memcached實例的多站點功能很有用)

不幸的是,它在django內置devserver上運行良好,但是當我嘗試使用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導入模塊的方式有什么不同嗎?

也許關於devserver的單進程,單線程性質?

我已經為此苦苦掙扎了幾天,任何幫助將不勝感激

額外信息:

  • Webfaction共享托管(centos)
  • 阿帕奇2
  • Python 2.5
  • Django 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裝飾器與一些中間件一起工作以找出當前站點。 他們來了:

decorators.py:

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

和middleware.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中發生是沒有意義的)

編輯:我在Django文檔中找到了devserver和apache之間的差異列表

Devserver將已安裝的應用程序添加到sys.path中,而Apache不會。

也許與它有關?

您是否在settings.py中設置了CACHE_BACKEND 當DEBUG = True時,這不是問題,因為我相信已安裝了虛擬后端,但是在生產中,即使您正在編寫自己的后端,也需要設置此值,假定為leyreley。

緩存后端文檔

如果已設置並且仍然有問題,請嘗試切換到虛擬緩存模塊或本地內存模塊(即使這不是一個很好的生產設置),以查看這些功能是否可行,如果可行,則可能會丟失WSGI的python路徑中的軟件包,例如python-memcached

問題的根源是sys.path我必須確保設置的mod_wsgi與開發服務器具有相同的sys.path,並且軟件包的多余副本都留在了它們不屬於的地方(由於重構不是t通過版本控制應用於服務器)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM