如何正确设置Flask + uWSGI + SQLAlchemy以避免数据库连接问题

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

我正在将Flask应用程序与SQLAlchemy和uWSGI服务器一起使用。一个众所周知的问题是,uWSGI在分叉期间通过所有过程复制了连接。网络上有些关于如何解决此问题的信息,但是似乎有两个主要选项:

  • 在uWSGI的配置中使用lazy-apps = true(不推荐使用,因为它会占用大量内存)
  • 使用uWSGI的@postfork装饰器在分叉后为每个新进程启动新的新连接后关闭连接,但我不清楚在Flask应用程序中何时以及如何使用它。

这是我的应用程序的示例:

# file: my_app/app.py

db = SQLAlchemy()


def create_app():
    app = Flask(__name__)
    app.config.from_pyfile(f'../config/settings.py')
    db.init_app(app)
    db.create_all(app=app)
    return app

run.py文件的示例:

# file: run.py
from my_app/app import create_app


app = create_app()
if "__main__" == __name__:
    app.run(debug=app.config["DEBUG"], port=5000)

所以问题是执行postfork的位置和方式如何正确设置uWSGI的服务器以在每个进程上使用隔离的连接而不使用lazy-apps = true

flask flask-sqlalchemy uwsgi
1个回答
0
投票

通常,您需要使用uwsgi提供的@postfork装饰器。我们没有使用SQLAlchemy,但我认为您也可以根据情况调整我们的解决方案。

这是我们的uwsgi配置的摘录:

[uwsgi]
strict = true

; process management
master = true
vacuum = true
pidfile = /tmp/uwsgi.pid

enable-threads = true
cpu-affinity = 1
processes = 4
threads = 2
mules = 2
...

这是使用@postfork创建进程安全的数据库连接的应用程序初始化代码。

from flask import Flask
from uwsgidecorators import postfork

from app.lib.db import DB  # DB object will be replaced by SQLAlchemy on your side

app = Flask(__name__)

# due to uwsgi's copy-on-write semantics workers need to connect to database
# to preserve unique descriptors after fork() is called in master process
@postfork
def db_reconnect():
    # Open the DB connection and log the event
    app.db = DB(config.get('db', 'host'),
                config.get('db', 'user'),
                config.get('db', 'pass'),
                config.get('db', 'name'))

在我们的情况下,所有初始化代码都放在__init__.pyapp文件夹中,但我认为将其迁移到app.py文件中不会有任何困难。

让我知道您是否还会遇到其他问题。

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