也许这是完全正常的行为,但我觉得django_session
表比它应该的大得多。
首先,我每天运行以下清理命令,因此过期的会话导致 的大小:
DELETE FROM %s WHERE expire_date < NOW()
数字:
SESSION_COOKIE_AGE
设置为默认值,为期2周所以,我猜测Django还会为访问该网站的所有机器人生成会话密钥,并且机器人不会存储cookie,因此它会不断生成新的cookie。
但......这是正常行为吗?是否有一个设置,以便Django不会为匿名用户生成会话,或者至少......没有会话的用户没有使用会话?
答案 0 :(得分:17)
经过一些调试后,我设法找出了问题的原因。
我的一个中间件(以及我的大部分观点)中都有request.user.is_authenticated()
。
django.contrib.auth
中间件将request.user
设置为LazyUser()
来源:http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/middleware.py?rev=14919#L13(我不明白为什么会有return None
,但确定......)
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
LazyUser
调用get_user(request)
来获取用户:
来源:http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/middleware.py?rev=14919#L5
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
get_user(request)
方法执行user_id = request.session[SESSION_KEY]
来源:http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/init.py?rev=14919#L100
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
在访问会话时将accessed
设置为true:
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
这导致会话初始化。该错误是由错误的会话后端引起的,当accessed
设置为true时,该会话后端也会生成会话...
答案 1 :(得分:3)
机器人是否可以访问您在用户会话中设置任何内容的任何页面(即使对于匿名用户),或者您使用session.set_test_cookie()
的任何页面(例如,调用此方法时Django的默认登录视图) ?在这两种情况下,都会创建一个新的会话对象。在robots.txt中排除此类网址应该会有所帮助。
答案 2 :(得分:0)
对于我的情况,我错误地在SESSION_SAVE_EVERY_REQUEST = True
中设置了settings.py
而没有理解其确切含义。
然后,对我的django服务的每个请求都会生成一个会话条目,尤其是来自上游负载均衡器的心跳测试请求。几天后#39;跑步,django_session
桌子变成了一张巨大的桌子。
答案 3 :(得分:-3)
Django提供management command to cleanup这些过期的会话!