在请求完成之前删除了请求的会话。例如,用户可能已在并发请求中注销

时间:2017-10-27 20:02:02

标签: python django

我有一个Python / Django应用程序,有时有超过100个用户登录。有一天,我在Django错误日志中找到了这个:

The request's session was deleted before the request completed. 
The user may have logged out in a concurrent request, for example.

虽然这封信是用非常容易理解的英文写的,但我不知道

  • 实际发生的事情
  • 为什么会发生
  • 我是否需要担心
  • 如果是,我怎样才能防止这种情况再次发生

我发现了一个几乎相同标题的问题,但不同之处在于我的设置中没有关于缓存的任何内容。

如果您需要任何代码,请在评论中告诉我。

谢谢你的时间!

10 个答案:

答案 0 :(得分:10)

实际发生的事情:当同一用户使用相同的会话密钥发出请求时,用户的会话被销毁(即,他们已注销,或会话已过期)。

为什么会发生这种情况:例如,如果用户打开了两个选项卡,并在其中一个选项卡中注销,则可能会发生这种情况,而另一个选项卡也会发出请求。如果两者都快速连续发生,那么就会遇到这个错误。

你需要担心它吗?:除非你在日志中看到很多这样的事件,否则会出现问题。如果你只发现一次错误,那就不用担心了。

答案 1 :(得分:1)

如果用户在“非活动”状态下尝试登录,也会发生此错误。

答案 2 :(得分:1)

由于其他原因,我也收到此错误:由于其他问题,数据库处于只读模式。

答案 3 :(得分:1)

这个错误使我忙了几个小时,直到最后我发现我的数据库被锁定是由于我没有保存对它所做的更改。保存数据即可解决问题。

答案 4 :(得分:0)

当运行django服务器的服务器用户(如果由与root用户不同的用户运行)在目录上没有足够的权限时,可能会发生此问题。 因此,服务器只有读,而不是写的权限。 您可以使用linux命令编辑项目目录的权限:

chmod u=rwx,g=rx,o= /project_path

其中u表示用户,g表示用户组,o表示其他用户。

您可以使用ls的-d选项检查目录的权限,如下所示:

ls -lhd /
ls -lhd /etc
ls -lhd /etc/opt
ls -lhd /etc/opt/$DJANGO_PROJECT

如果用户可能已在并发请求中注销,也会发生此错误。

答案 5 :(得分:0)

这也可能发生,因为您将会话存储在虚拟缓存后端中。 例如:

CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379/1",
            "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
    'dummy': {
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
        'LOCATION': 'unique-snowflake',
    }
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = os.environ.get('SESSION_CACHE_ALIAS', "dummy")

解决方案只是改变=:SESSION_CACHE_ALIAS =“默认”

(Redis是我的配置;您可以使用django.core.cache.backends.locmem.LocMemCache或Memcached或任何其他选项。 甚至可以将Session引擎从缓存更改为其他内容。

答案 6 :(得分:0)

在我的情况下,这是由于两个数据库服务器之间的复制延迟(在主[RW]-从模式[RO]下)引起的,因为我正在将一些请求路由到从服务器以便在DB之间执行负载分配。由于两台Redis服务器之间的复制延迟,使用两台Redis服务器作为缓存引擎时也会发生相同的事情。

我们修复了该问题,将会话请求强制发送到主服务器。

答案 7 :(得分:0)

如果你调用这个异常也会发生

request.session.clear()

当会话存在时(因为它未被使用或超时)。

可以通过检查并仅在使用时清除会话来解决:

if request.session:
    request.session.clear()

答案 8 :(得分:0)

就我而言,我已将数据库文件 (SQLite) 打开到数据库浏览器中。因此,这使得它被关闭以供后续请求使用。 尝试停止连接到您的数据库的其他内容。

答案 9 :(得分:0)

当硬盘上没有更多空间时也会发生这种情况,AWS EC2 实例遇到类似问题并且清理空间有帮助