Django / Memcached error: The request's session was deleted before the request completed
Django / Memcached error: The request's session was deleted before the request completed
这是完整的错误:请求的会话在请求完成之前被删除。例如,用户可能已在并发请求中注销。
我在使用我的缓存的会话中使用 python-memcached。每隔几天我就会遇到其中一个错误。它由 request.session.save() 上的 UpdateError 抛出。它来自 sessions/middleware.py 中的第 60 行。 99% 的时间一切正常。我在许多不同的 GET 和 POST 请求的 URL 上看到了这个错误。用户报告说他们没有单击注销按钮。他们还报告说这种情况会在登录后 5 分钟发生,因此他们的会话不会过期。一个多月以来,我的缓存中有 0 次驱逐,已经 运行ning 了。如果我 Google 这个错误,看起来以前没有人得到过它。
我认为与 memcached 的连接可能由于某种原因正在关闭。它在本地主机上 运行ning。我唯一一次看到此错误是在我将缓存配置设置为具有 memcached 运行ning 的服务器时,但它没有在该接口上侦听。这将在每个请求上生成这个确切的异常。那么有没有什么方法可以让 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 在 shell 中使用会话密钥,同时请求 运行ning。所以有些东西正在删除缓存键。我不知道它是 Django 还是 Memcached。 Memcached 确实说 STAT evictions 0
.
我做了这个中间件来解决这个问题。它似乎已经照顾它。还要检查您的文件描述符限制。
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
当我启用 Django 的 DummyCache 以防止在开发时缓存我的视图时,我也遇到了这个错误(请注意我使用 Redis 作为我的缓存后端)。
请务必在尝试访问您网站的管理员时禁用 DummyCache。
Django 文档给出了您看到错误的原因的提示:
Finally, Django comes with a “dummy” cache that doesn’t actually cache – it just implements the cache interface without doing anything.
我在我的 settings.py
文件中根据我正在处理的内容在这两行之间进行选择。
"BACKEND": 'django.core.cache.backends.dummy.DummyCache' if DEBUG else "django_redis.cache.RedisCache",
"BACKEND": "django_redis.cache.RedisCache",
在我的例子中,我使用 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
。
当我从备份(loaddata 左右)更新数据时,我在下次访问时看到这个错误。
因此,连同此类操作,有必要删除缓存中的相应条目:
cache.del('django.contrib.sessions.cached_dbo27db603b30jabewi7zkwd78b05zq0vf')
。 (当然也可以从redis客户端删除)
这是完整的错误:请求的会话在请求完成之前被删除。例如,用户可能已在并发请求中注销。
我在使用我的缓存的会话中使用 python-memcached。每隔几天我就会遇到其中一个错误。它由 request.session.save() 上的 UpdateError 抛出。它来自 sessions/middleware.py 中的第 60 行。 99% 的时间一切正常。我在许多不同的 GET 和 POST 请求的 URL 上看到了这个错误。用户报告说他们没有单击注销按钮。他们还报告说这种情况会在登录后 5 分钟发生,因此他们的会话不会过期。一个多月以来,我的缓存中有 0 次驱逐,已经 运行ning 了。如果我 Google 这个错误,看起来以前没有人得到过它。
我认为与 memcached 的连接可能由于某种原因正在关闭。它在本地主机上 运行ning。我唯一一次看到此错误是在我将缓存配置设置为具有 memcached 运行ning 的服务器时,但它没有在该接口上侦听。这将在每个请求上生成这个确切的异常。那么有没有什么方法可以让 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 在 shell 中使用会话密钥,同时请求 运行ning。所以有些东西正在删除缓存键。我不知道它是 Django 还是 Memcached。 Memcached 确实说 STAT evictions 0
.
我做了这个中间件来解决这个问题。它似乎已经照顾它。还要检查您的文件描述符限制。
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
当我启用 Django 的 DummyCache 以防止在开发时缓存我的视图时,我也遇到了这个错误(请注意我使用 Redis 作为我的缓存后端)。
请务必在尝试访问您网站的管理员时禁用 DummyCache。
Django 文档给出了您看到错误的原因的提示:
Finally, Django comes with a “dummy” cache that doesn’t actually cache – it just implements the cache interface without doing anything.
我在我的 settings.py
文件中根据我正在处理的内容在这两行之间进行选择。
"BACKEND": 'django.core.cache.backends.dummy.DummyCache' if DEBUG else "django_redis.cache.RedisCache",
"BACKEND": "django_redis.cache.RedisCache",
在我的例子中,我使用 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
。
当我从备份(loaddata 左右)更新数据时,我在下次访问时看到这个错误。
因此,连同此类操作,有必要删除缓存中的相应条目:
cache.del('django.contrib.sessions.cached_dbo27db603b30jabewi7zkwd78b05zq0vf')
。 (当然也可以从redis客户端删除)