问题:
tornado多进程+sqlalchemy连接池,经常报错:mysql server has gone away
原因分析:
父进程创建了子进程之后,子进程会使用调用父进程的mysql连接;当这个子进程退出时,连接被关闭;当父进程再创建子进程时,这个子进程同样调用了父进程的mysql连接,而此时mysql连接已经被上一个进程关闭,但当前子进程并不知道这一点,所以就会报错。
解决:SQLAlchemy 1.3 Documentationdocs.sqlalchemy.org
from sqlalchemy import event
from sqlalchemy import exc
import os
engine = create_engine("...")
#多进程相关配置,Pool使用事件来检测自身,以便在子进程中自动使连接无效
@event.listens_for(engine, "connect")
def connect(dbapi_connection, connection_record):
connection_record.info['pid'] = os.getpid()
@event.listens_for(engine, "checkout")
def checkout(dbapi_connection, connection_record, connection_proxy):
pid = os.getpid()
if connection_record.info['pid'] != pid:
connection_record.connection = connection_proxy.connection = None
raise exc.DisconnectionError(
"Connection record belongs to pid %s, "
"attempting to check out in pid %s" %
(connection_record.info['pid'], pid)
)