Подтвердить что ты не робот

Огромный стол сеанса Django, нормальное поведение или ошибка?

Возможно, это вполне нормальное поведение, но мне кажется, что таблица django_session намного больше, чем она должна быть.

Прежде всего, я запускаю следующую команду очистки ежедневно, поэтому размер не, вызванный истекшими сеансами:

DELETE FROM %s WHERE expire_date < NOW()

Цифры:

  • Каждый день у нас около 5000 уникальных посетителей (исключены боты).
  • Для параметра SESSION_COOKIE_AGE установлено значение по умолчанию, 2 недели
  • Таблица имеет немного более 1,000,000 строк

Итак, я предполагаю, что Django также генерирует ключи сеанса для всех ботов, которые посещают сайт, и что боты не хранят файлы cookie, поэтому он постоянно генерирует новые файлы cookie.

Но... это нормальное поведение? Есть ли настройка, поэтому Django не будет генерировать сеансы для анонимных пользователей или, по крайней мере,... сеансов для пользователей, которые не используют сеансы?

4b9b3361

Ответ 1

После небольшой отладки мне удалось проследить причину проблемы. У одного из моих посредников (и большинства моих представлений) есть 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? ред = 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...

Ответ 2

Возможно ли, чтобы роботы имели доступ к любой странице, на которой вы устанавливали что-либо в сеансе пользователя (даже для анонимных пользователей), или на любой странице, где вы используете session.set_test_cookie() (например, по умолчанию для входа в Django при вызове этого метода)? В обоих случаях создается новый объект сеанса. Исключение таких URL-адресов в файле robots.txt должно помочь.

Ответ 3

В моем случае я неправильно установил SESSION_SAVE_EVERY_REQUEST = True в settings.py, не понимая точного значения.

Затем каждый запрос к моей службе django будет генерировать запись сеанса, особенно запрос на проверку пульса от балансировщиков нагрузки вверх. После нескольких дней работы таблица django_session превратилась в огромную.