21

也许这是完全正常的行为,但我觉得这张django_session桌子比它应该的要大得多。

首先,我每天运行以下清理命令,因此大小不是过期会话引起的:

DELETE FROM %s WHERE expire_date < NOW()

号码:

  • 我们每天有大约 5000 名唯一身份访问者(不包括机器人)。
  • SESSION_COOKIE_AGE设置为默认值,2周
  • 该表有超过1,000,000 行

因此,我猜测 Django 还会为访问该站点的所有机器人生成会话密钥,并且这些机器人不存储 cookie,因此它会不断生成新的 cookie。

但是……这是正常的行为吗?是否有设置让 Django 不会为匿名用户生成会话,或者至少......没有为不使用会话的用户生成会话?

4

4 回答 4

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:

来源:http ://code.djangoproject.com/browser/django/trunk/django/contrib/sessions/backends/base.py?rev=14919#L183

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 时也会生成会话...

于 2010-12-16T01:33:00.420 回答
3

机器人是否可以访问您在用户会话中设置任何内容的任何页面(即使对于匿名用户),或者您使用的任何页面session.set_test_cookie()(例如 Django 的默认登录视图调用此方法)?在这两种情况下,都会创建一个新的会话对象。在 robots.txt 中排除此类 URL 应该会有所帮助。

于 2010-12-15T08:46:19.577 回答
0

就我而言,我SESSION_SAVE_EVERY_REQUEST = Truesettings.py不了解确切含义的情况下错误地插入。

然后对我的 django 服务的每个请求都会生成一个会话条目,尤其是来自上游负载均衡器的心跳测试请求。经过几天的运行,django_session桌子变成了一张巨大的桌子。

于 2015-03-25T07:29:11.920 回答
-3

Django 提供了一个管理命令来清理这些过期的会话!

于 2010-12-15T02:35:51.580 回答