我正在使用自定义缓存后端来包装内置缓存后端,以便我可以将当前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的单进程,单线程特性?
我几天来一直在努力奋斗,任何帮助都会受到赞赏
额外信息:
更多详情: - 我已经设置了缓存后端(它正在工作,因为你可以看到它在回溯中导入正确的模块) - 模块中有一个名为“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文档中找到了list of the differences between devserver and apache,其中说明了
Devserver将已安装的应用添加到 sys.path,Apache没有。
也许这与它有关?
答案 0 :(得分:1)
您是否在settings.py中设置了CACHE_BACKEND
?当DEBUG = True时,这不是问题,因为我相信安装了一个虚拟后端,但是在生产中,即使你正在编写自己的后端,也需要设置这个值,presumedley。
如果已设置并且您仍然遇到问题,请尝试切换到虚拟缓存模块或本地内存(即使这不是一个好的生产设置),看看这些是否有效,如果有,那么你可能在您的WSGI的python路径中缺少一个包,如python-memcached
答案 1 :(得分:0)
问题的根源是sys.path
我必须确保mod_wsgi设置与开发服务器具有相同的sys.path,并且没有额外的软件包副本留在他们不属于的地方(从某种方式通过版本控制未应用于服务器的重构)