Django 会话间歇性失败

问题描述 投票:0回答:1

我去年为我举办的一个名为“纳什维尔桌面日”的社区活动编写了一个应用程序。该应用程序允许人们扫描二维码,与白天可以玩的游戏进行互动。在本地运行得很好。然而,当我将其推送到 Fly.io 时,它会运行,但会可靠地丢弃会话。我的意思是我可以登录,浏览到一两页,然后会话就消失了。如果我停留在同一页面并重新加载几次,甚至会发生这种情况。

它不会立即发生,或者我认为数据库可能是问题所在。但 15-30 秒后,或者加载了几个页面之后——噗。该活动将于下周六举行,此应用程序必须准备就绪。

我很想认为这可能是一个配置问题,但这个应用程序去年运行,几乎完美无缺,今年我只做了一些小更新。

Django 4.1.7
Python 3.8.18
Database is SQLite

INSTALLED_APPS = [
    'ntd.apps.NtdConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'whitenoise.runserver_nostatic',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'ntd.middleware.request_logger.RequestLoggerMiddleware',
]

我完成的一些调试:

我添加了一个简单的日志记录中间件并打印

request.session.session_key
request.path
。在本地,每次重新加载都会显示
attendee_uuid
(我关心的值)和其他两个值。当我将该代码推送到 Fly 时,所有三个值都会打印几次,然后开始打印 None。

我还尝试恢复到去年活动中使用的分支,因为我知道代码有效。我刚刚将其推到 Fly 上进行测试,我得到了相同的行为。从数据库加载数据,这允许我浏览一些公共页面,但它不会维持会话,这意味着它不适合用户特定的功能。

一些额外信息:我刚刚注意到 Django 管理员也将我注销了。

所以会话肯定是问题所在。请帮忙!

django sqlite django-sessions fly
1个回答
0
投票

问题在于,fly.io 自动水平缩放应用程序,并将其放置在负载均衡器后面。

如果您使用的会话存储是应用程序的单个实例所独有的,例如非共享文件系统上的文件存储、数据库存储(如果每个应用程序实例使用单独的数据库等),那么会话似乎会随机消失如果负载均衡器碰巧将请求路由到与创建会话的计算机不同的计算机。

长期解决方案是对应用程序的所有实例使用单个数据库;我建议使用 Fly Postgress,但 Fly.io 提供了相当全面的选项概述here

短期解决方案是防止应用程序扩展;如果应用程序的实例不超过一个,则没有问题。对于许多用户来说,如果他们的应用程序不需要扩展,并且他们不担心缺乏冗余,这也是可以接受的。

© www.soinside.com 2019 - 2024. All rights reserved.