[英]cache backend works on devserver but not mod_wsgi
I am using a custom cache backend to wrap the built-in cache backends so that I can add the current site_id to all the cache_keys (this is useful for multi-site functionality with a single memcached instance) 我正在使用自定义缓存后端来包装内置缓存后端,以便可以将当前site_id添加到所有cache_keys中(这对于具有单个memcached实例的多站点功能很有用)
unfortunately it works great on the django built-in devserver, but give a nasty error when I try to run it on the live server with mod_wsgi 不幸的是,它在django内置devserver上运行良好,但是当我尝试使用mod_wsgi在实时服务器上运行它时,却出现了一个讨厌的错误
Here is the traceback from my error log: 这是我的错误日志的回溯:
[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'
if I run the devserver on the same machine (the live server) it works fine... I am able to do this without trouble: 如果我在同一台机器(实时服务器)上运行devserver,则可以正常工作...我能够做到这一点而没有麻烦:
$ cd /home/jiaaro/webapps/op_wsgi/myProject
$ python2.5 manage.py runserver
and in a separate ssh session... 并在单独的ssh会话中...
$ wget 127.0.0.1:8000
The pages are served correctly, using memcached, and the live database. 使用memcached和实时数据库可以正确提供页面。 is there something different about the way mod_wsgi imports modules that I should know about? 我应该了解的mod_wsgi导入模块的方式有什么不同吗?
maybe something about the single-process, single-threaded nature of the devserver? 也许关于devserver的单进程,单线程性质?
I have been struggling with this for days now, any help would be appreciated 我已经为此苦苦挣扎了几天,任何帮助将不胜感激
Extra info: 额外信息:
More Details: - I have set the cache backend (and it is working since you can see it importing the correct module in the traceback) - There is a class called "CacheClass" in the module: 更多详细信息:-我已经设置了缓存后端(并且可以正常工作,因为您可以看到它在追溯中导入了正确的模块)-在模块中有一个名为“ CacheClass”的类:
site_settings/cache_wrapper.py : 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)
THe accept_site decorator works in conjunction with some middleware to figure out the current site. accept_site装饰器与一些中间件一起工作以找出当前站点。 Here they are: 他们来了:
decorators.py: 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
and the middleware.py 和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)
All of this works using the devserver, using the same settings as the wsgi server and configured with the same python path (as far as I can see) 所有这些工作都使用devserver进行,使用与wsgi服务器相同的设置并配置了相同的python路径(据我所知)
At this point I'm hoping I've created an import loop somewhere (though that wouldn't make sense that it only occurs in the devserver) 在这一点上,我希望我在某个地方创建了一个导入循环(尽管这仅在devserver中发生是没有意义的)
edit: I found a list of the differences between devserver and apache in the django docs which says, 编辑:我在Django文档中找到了devserver和apache之间的差异列表 ,
Devserver adds installed apps to sys.path, Apache does not. Devserver将已安装的应用程序添加到sys.path中,而Apache不会。
Maybe that has something to do with it? 也许与它有关?
Have you set the CACHE_BACKEND
in your settings.py? 您是否在settings.py中设置了CACHE_BACKEND
? When DEBUG=True, this is not an issue, as I believe a dummy backend is installed, but in production, you will need to set this value, presumedley even if you're writing your own backend. 当DEBUG = True时,这不是问题,因为我相信已安装了虚拟后端,但是在生产中,即使您正在编写自己的后端,也需要设置此值,假定为leyreley。
If that's set and you're still having issues, try switching to the dummy cache module or the local memory one (even though this isn't a good production setup) to see if those work, and if they do, you may be missing a package in your WSGI's python path like python-memcached 如果已设置并且仍然有问题,请尝试切换到虚拟缓存模块或本地内存模块(即使这不是一个很好的生产设置),以查看这些功能是否可行,如果可行,则可能会丢失WSGI的python路径中的软件包,例如python-memcached
问题的根源是sys.path
我必须确保设置的mod_wsgi与开发服务器具有相同的sys.path,并且软件包的多余副本都留在了它们不属于的地方(由于重构不是t通过版本控制应用于服务器)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.