Ошибка Django / Memcached: сеанс запроса был удален до его завершения
Вот полная ошибка: сеанс запроса был удален до его завершения. Пользователь, возможно, вышел из системы по параллельному запросу, например.
Я использую python-memcached с моими сессиями, используя мой кеш. Каждые несколько дней я получаю одну из этих ошибок. Его генерирует ошибка UpdateError по запросу.session.save(). Это происходит из строки 60 в session /middleware.py. 99% времени все работает нормально. Я видел эту ошибку на многих разных URL для запросов GET и POST. Пользователи сообщают, что не нажимают кнопку выхода из системы. Они также сообщают, что это происходит через 5 минут после входа в систему, поэтому их сеансы не истекают. У меня 0 клонов в моем кеше за месяц, когда он работал. Если я погуглю эту ошибку, то, похоже, никто ее раньше не получал.
Я думаю, что по какой-то причине соединения с memcached могут закрываться. Это работает на localhost. Единственный раз, когда я увидел эту ошибку, это когда я установил свою конфигурацию кэша на сервер, на котором запущен memcached, но он не прослушивал этот интерфейс. Это будет генерировать это точное исключение при каждом запросе. Так есть ли какой-нибудь способ, которым memcache отказывается слушать секунду или две или разрывает соединения?
Вот мои настройки:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
'TIMEOUT': 1209600, # Two weeks
},
}
SESSION_SAVE_EVERY_REQUEST = True
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_COOKIE_SECURE = CSRF_COOKIE_SECURE = True
SESSION_COOKIE_AGE = 60 * 90 # In 90 minutes
Кажется, верный способ вызвать эту ошибку - запустить cache.delete с ключом сеанса в оболочке во время выполнения запроса. Так что что-то удаляет ключи кеша. Я не знаю, является ли это Django или Memcached. Memcached говорит STAT evictions 0
,
2 ответа
Я сделал это промежуточное ПО для решения проблемы. Кажется, об этом позаботились. Также проверьте ограничения файловых дескрипторов.
class SLSessionMiddleware(SessionMiddleware):
"""
Fixes a bug where sessions sometime fail to be set. Catches the error 10 times and gives up.
"""
def process_response(self, request, response):
last_exception = None
for i in range(10):
try:
return super().process_response(request, response)
except Exception as e:
request.session.cycle_key()
time.sleep(1)
last_exception = e
raise last_exception
В моем случае я использую
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
.
Я вижу эту ошибку при следующих доступах, когда обновляю данные из резервной копии (loaddata или около того).
Поэтому вместе с таким действием необходимо удалить соответствующие записи в кеше:cache.del('django.contrib.sessions.cached_dbo27db603b30jabewi7zkwd78b05zq0vf')
. (Или, конечно, вы можете удалить из клиента Redis или около того.)
Я также столкнулся с этой ошибкой, когда включил DummyCache в Django, чтобы предотвратить кэширование моих представлений во время разработки (обратите внимание, что я использую Redis в качестве своего механизма кэширования).
Обязательно отключите DummyCache при попытке доступа к администратору вашего сайта.
Документация Django дает подсказку о том, почему вы видите ошибку:
Наконец, Django поставляется с "фиктивным" кешем, который фактически не кешируется - он просто реализует интерфейс кеша, ничего не делая.
Я альтернатива между этими двумя строчками в моем settings.py
файл в зависимости от того, над чем я работаю.
"BACKEND": 'django.core.cache.backends.dummy.DummyCache' if DEBUG else "django_redis.cache.RedisCache",
"BACKEND": "django_redis.cache.RedisCache",