Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在多个uWSGI过程中使用炼金术_Python_Mysql_Flask_Sqlalchemy_Flask Sqlalchemy - Fatal编程技术网

Python 在多个uWSGI过程中使用炼金术

Python 在多个uWSGI过程中使用炼金术,python,mysql,flask,sqlalchemy,flask-sqlalchemy,Python,Mysql,Flask,Sqlalchemy,Flask Sqlalchemy,我一直在与Flask应用程序中的一个持续错误作斗争: OperationalError: (_mysql_exceptions.OperationalError) (2006, 'MySQL server has gone away') 我正在使用mySQL服务器实例和Flask SQLAlchemy模块。我仔细检查了mySQL实例上连接的过期时间和SQLAlchemy配置中的重置时间。没有问题,连接池在mySQL连接过期之前重置。我得出的结论是,一定是有什么问题导致连接关闭,然后该连接的下一

我一直在与Flask应用程序中的一个持续错误作斗争:

OperationalError: (_mysql_exceptions.OperationalError) (2006, 'MySQL server has gone away')
我正在使用mySQL服务器实例和Flask SQLAlchemy模块。我仔细检查了mySQL实例上连接的过期时间和SQLAlchemy配置中的重置时间。没有问题,连接池在mySQL连接过期之前重置。我得出的结论是,一定是有什么问题导致连接关闭,然后该连接的下一个用户阻塞

我正在使用uWSGI运行Flask应用程序,uWSGI生成了四个进程。如果切换到单个进程,则无法重现错误。我猜进程是通过共享连接池相互踩踏的。我添加了以下函数,以便在uWSGI分叉进程时运行

from uwsgidecorators import postfork

@postfork
def reset_db_connections():
    db.engine.dispose()
启动时工作正常,当多个请求同时进入时,似乎可以解决问题。但是,现在当一个进程被重置时,该进程上的下一个请求会出现一个类似但不相同的SQL Server消失错误。以下是数据库的初始设置代码

def configure_db():
    from my_application.models import SomeModel
    db.create_all()

db = SQLAlchemy(app, session_options={'expire_on_commit': False})
configure_db()
数据库的典型用法如下所示:

def save(self):
    try:
        db.session.add(self)
        db.session.commit()
    except Exception, ex:
        app.logger.error("Error saving campaign: %s" % ex)
        db.session.rollback()
Reads是以下两种风格之一:

user = db.session.query(User).filter(User.email == email).scalar()
user = User.query.filter(User.email == email).scalar()
我的理解是Flask SQLAlchemy使用范围会话,因此它们应该在多进程环境中提供一些保护。我需要重置fork上的连接池吗?分叉时我是否也应该检查实时会话

更新: 我已将叉子更改为:

@postfork
def reset_db_connections():
    db.session.close_all()
    db.engine.dispose()
    db.create_scoped_session()
我仍然得到操作错误,但它只发生在fork期间,并且似乎不会干扰请求。堆栈跟踪不包括fork,但这不允许我捕获它

回溯(最近一次呼叫最后一次):

文件 “/home/vagrant/env/local/lib/python2.7/site packages/sqlalchemy/pool.py”, 第636行,在 仙女。重置(池)

文件 “/home/vagrant/env/local/lib/python2.7/site packages/sqlalchemy/pool.py”, 第774行,输入复位 self.\u reset\u agent.rollback()

文件 “/home/vagrant/env/local/lib/python2.7/site packages/sqlalchemy/engine/base.py”, 第1563行,在回滚中 self.\u do\u rollback()

文件 “/home/vagrant/env/local/lib/python2.7/site packages/sqlalchemy/engine/base.py”, 第1601行,in_do_回滚 self.connection.\u回滚\u impl()

文件 “/home/vagrant/env/local/lib/python2.7/site packages/sqlalchemy/engine/base.py”, 第670行,在“回滚”impl中 self.\u handle\u dbapi\u异常(e,None,None,None,None)

文件 “/home/vagrant/env/local/lib/python2.7/site packages/sqlalchemy/engine/base.py”, 第1341行,在_handle_dbapi_异常中 exc_信息

文件 “/home/vagrant/env/local/lib/python2.7/site packages/sqlalchemy/util/compat.py”, 第199行,从原因提升 重新释放(类型(异常),异常,tb=exc_tb)

文件 “/home/vagrant/env/local/lib/python2.7/site packages/sqlalchemy/engine/base.py”, 第668行,在“回滚”impl中 self.engine.dialogue.do_回滚(self.connection)

文件 “/home/vagrant/env/local/lib/python2.7/site packages/sqlalchemy/dialogs/mysql/base.py”, 第2519行,在do_回滚中 dbapi_连接.回滚()


您必须使用lazy apps=true选项来设置uwsgi

看看这个答案:

我不会使用“lazy”选项,因为它已被弃用

当使用主进程处理多个进程时,uwsgi 在主进程中初始化应用程序,然后复制 应用程序转移到每个工作进程。问题是如果你打开一个 数据库连接在初始化应用程序时 多个进程共享同一连接,这会导致错误 上面

在某些情况下,如使用flask_admin或在
app/\uuuu init\uuuuuuuuuuupy
中调用
Base.metadata.create_all()
,您的应用确实在导入时已经与数据库建立了连接。使用
lazy apps=false
uwsgi在导入模块后分叉,从而将连接的文件描述符复制到子级。使用
lazy apps=true
uwsgi自身分叉,然后进行导入。这样,每个子进程都有自己的连接

uWSGI尝试(ab)使用fork()调用的Copy-On-Write语义 只要可能。默认情况下,它将在加载 应用程序共享尽可能多的内存。如果这 由于某些原因,这种行为是不受欢迎的,请使用lazy apps选项。 这将指示uWSGI在每个工作人员完成任务后加载应用程序 fork()