Flask-Session文件系统存储并发请求会话数据丢失问题求助
问题原因
flask-session的文件系统存储后端默认逻辑是:每个请求启动时从文件加载session初始数据,请求结束时才将修改后的session写回文件。当多个并发请求同时处理时,所有请求初始读取的都是同一版session状态,各自修改后独立写回文件——后完成的请求会直接覆盖先完成的写入结果,最终只有最后写入的少数key能保留,其余全部丢失。
解决方案
1. 启用文件锁机制
flask-session的文件系统后端支持通过锁来避免并发写入冲突,只需添加锁目录配置(确保目录有读写权限):
app.config['SESSION_FILE_LOCK_DIR'] = '/tmp/flask_session_locks' # 可自定义锁文件存储路径
该配置会让每个session操作前先获取文件锁,保证同一时间只有一个请求能修改并写入session文件,从根源上避免覆盖。
2. 手动显式保存session
在每个写入请求的末尾主动调用session.save(),让修改后的session立即写入文件,而非等待请求结束自动保存。修改/write接口代码:
from flask import Flask, session, request # 补充缺失的request导入 # ... 原有配置代码 ... @app.route('/write', methods=['POST']) def write(): key = request.form['key'] value = request.form['value'] session[key] = value session.save() # 显式保存,立即持久化最新session状态 print(session) return ""
这样每个写入请求完成修改后会立刻更新session文件,后续并发请求能读取到最新的session数据,避免覆盖丢失。
3. 改用原子性存储后端
如果文件系统锁仍有局限,可替换为Redis这类天然支持原子更新的存储后端。Redis的哈希结构能原子性更新单个key,完全适配并发场景,配置示例:
import redis from flask_session import Session from flask import Flask, session, request app = Flask(__name__) app.config['SESSION_TYPE'] = 'redis' app.config['SESSION_REDIS'] = redis.Redis(host='localhost', port=6379) app.config['SECRET_KEY'] = "super secret key" # ... 其余cookie配置保持不变 ... server_session = Session() server_session.init_app(app)
该方案需要额外部署Redis服务,但能彻底解决文件系统的并发覆盖问题。
额外注意事项
- 原有代码遗漏了
request对象的导入,必须补充,否则接口会直接报错。 - 若使用文件锁,需确保
SESSION_FILE_LOCK_DIR指定的目录对Flask进程有读写权限,否则锁机制无法生效。
内容的提问来源于stack exchange,提问作者a.ilchinger
相关产品推荐
相关产品推荐

