我正在开发Flask应用程序,并且正在将其设置在外部服务器上。我将其设置为与gunicorn和nginx一起运行。我遇到的问题是,当用户向应用程序中输入数据时,该用户无法始终如一地访问该信息(即,在用户注册后,该应用程序每5或6次仅识别其登录信息一次)。
深入研究它之后,我相信问题在于数据库会话永远不会在请求结束时被删除。好像flask在请求结束时未弹出应用上下文。但是我不确定为什么或如何解决。
我已执行的故障排除步骤为: 1)经过验证的信息正在进入数据库-是 2)使用生产配置设置在本地运行flask开发服务器-工作正常。 3)在本地计算机上运行gunicorn-我这样做并遇到了数据访问不一致的相同问题 4)将Gunicorn工作者的数量从4个减少到1个-我做到了,并且用户数据库访问正常 5)检查flask-sqlalchemy是否在请求结束时删除会话-发现运行gunicorn时函数未调用db.session.remove。 6)检查app.do_teardown_appcontext是否正在被调用-运行gunicorn时未被调用。运行开发服务器时将调用它。 7)检查是否在请求结束时调用了appcontext pop-不,在运行gunicorn时未调用。是的,正在运行开发服务器时被调用。 8)检查请求上下文弹出消息-两者都可以。
烧瓶config.py
class Config(object):
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')
SQLALCHEMY_TRACK_MODIFICATIONS = False
class ProductionConfig(Config):
DEBUG = False
TESTING = False
class DevelopmentConfig(Config):
DEBUG = True
TESTING = False
** 初始化 .py
def register_extensions(app):
"""Register extension with app."""
db.init_app(app)
migrate.init_app(app, db)
login.init_app(app)
def create_app(configClass=None):
app = Flask(__name__)
if configClass is None:
if app.config['ENV'] == 'production':
app.config.from_object(config.ProductionConfig)
else:
app.config.from_object(config.DevelopmentConfig)
else:
app.config.from_object(configClass)
#app.app_context().push()
register_extensions(app)
register_blueprints(app)
return app
主管配置
[program:Ask]
command=/home/ubuntu/project/venv/bin/gunicorn -b localhost:8000 -w
4 Ask:app
directory=/home/ubuntu/project
user=ubuntu
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
运行开发服务器时的拆机呼叫: 拆解功能:[。shutdown_session位于0x7f55df9718c0>] 请求上下文弹出调用 请求上下文弹出调用应用程序执行拆解请求 应用上下文弹出 应用上下文调用拆解appcontext 做拆解appcontext调用,即将调用拆解函数 拆解appcontext函数称为 关闭会话调用会话删除
使用Gunicorn时的拆机呼叫 拆解功能:[。shutdown_session位于0x7f0dfa579440>] 请求上下文弹出调用 req上下文弹出调用应用程序执行拆卸请求
更新
我发现解决方案是从create_app函数中删除app.app_context()。push()。我最初添加此内容是为了推送应用程序上下文,以允许多个表单的选择列表能够访问数据库以自动填充。为了适应删除应用程序上下文推送,我已将调用填充到表单选择列表中。这与烧瓶文档有关使用应用程序上下文的建议一致。 https://flask.palletsprojects.com/en/1.1.x/appcontext/