巨大的Django会话表,正常行为还是bug?
也许这是完全正常的行为,但我觉得巨大的Django会话表,正常行为还是bug?,django,django-sessions,Django,Django Sessions,也许这是完全正常的行为,但我觉得django_session表比它应该的要大得多 首先,我每天运行以下清理命令,这样大小就不会由过期会话引起了: DELETE FROM %s WHERE expire_date < NOW() 从%s中删除过期日期
django_session
表比它应该的要大得多
首先,我每天运行以下清理命令,这样大小就不会由过期会话引起了:
DELETE FROM %s WHERE expire_date < NOW()
从%s中删除过期日期
编号:
- 我们每天约有5000名独立访客(不包括机器人)
设置为默认值2周SESSION\u COOKIE\u AGE
- 该表的行数略多于1000000行
但是。。。这是正常的行为吗?是否有设置使Django不会为匿名用户生成会话,或者至少。。。对于不使用会话的用户,没有会话?Django为这些过期会话提供了一个解决方案 机器人是否可以访问您在用户会话中设置任何内容的任何页面(即使是匿名用户),或者访问您使用
会话的任何页面。set_test_cookie()
(例如,Django在此方法中调用的默认登录视图)?在这两种情况下,都会创建一个新的会话对象。排除robots.txt中的此类URL应该会有所帮助。经过一段时间的调试,我已经设法找到了问题的原因。
我的一个中间件(以及我的大多数视图)中有一个request.user.is\u authenticated()
django.contrib.auth
中间件将request.user
设置为LazyUser()
来源:(我不明白为什么那里有一个返回None
,但是ok…)
LazyUser
调用get\u user(请求)
获取用户:
资料来源:
get\u user(request)
方法执行一个user\u id=request.session[session\u KEY]
资料来源:
访问会话时,将访问的设置为true:
资料来源:
这将导致会话初始化。该错误是由错误的会话后端造成的,当accessed
设置为true时,该后端也会生成会话 就我的情况而言,我在settings.py
中错误地设置了SESSION\u SAVE\u EVERY\u REQUEST=True
,但没有理解确切含义
然后,对django服务的每个请求都会生成一个会话条目,特别是来自上游负载平衡器的心跳测试请求。运行了几天之后,django_会话
表变成了一个巨大的表。正如我在最初的问题中所说,我不是在谈论过期的会话。我已经运行了一个每日清理命令(不是Django版本,因为这个命令在你达到这个会话量之前很久就消失了)。问题是,在一个中间件中,我使用会话来检测是否需要设置一些cookie。谢谢你给我指出了正确的方向:)+1我知道这个答案是很久以前写的,但我看到了同样的问题。这个解释似乎有道理,但有解决办法吗?谢谢对我来说,修复方法是确保会话在未真正使用时不会生成。我的一个中间件在所有情况下都将会话设置为已访问
,从而在每个机器人的每个页面视图上生成会话。嗯。。。那一定和我的问题不一样了。我尝试创建一个全新的django 1.4应用程序,如果用户是匿名的,并且以前没有访问过,django.contrib.auth.views.login似乎会导致保存一个新会话。我为此创建了一个新问题:。如果你能看一下就好了。谢谢
class AuthenticationMiddleware(object):
def process_request(self, request):
assert hasattr(request, 'session'), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."
request.__class__.user = LazyUser()
return None
class LazyUser(object):
def __get__(self, request, obj_type=None):
if not hasattr(request, '_cached_user'):
from django.contrib.auth import get_user
request._cached_user = get_user(request)
return request._cached_user
def get_user(request):
from django.contrib.auth.models import AnonymousUser
try:
user_id = request.session[SESSION_KEY]
backend_path = request.session[BACKEND_SESSION_KEY]
backend = load_backend(backend_path)
user = backend.get_user(user_id) or AnonymousUser()
except KeyError:
user = AnonymousUser()
return user
def _get_session(self, no_load=False):
"""
Lazily loads session from storage (unless "no_load" is True, when only
an empty dict is stored) and stores it in the current instance.
"""
self.accessed = True
try:
return self._session_cache
except AttributeError:
if self._session_key is None or no_load:
self._session_cache = {}
else:
self._session_cache = self.load()
return self._session_cache