使用sshtunnel连接远程MySQL时出现连接丢失错误求助
解决使用sshtunnel连接远程MySQL时出现的Lost Connection错误
我之前也碰到过一模一样的问题,这个2013错误大多是因为SSH隧道的生命周期没和SQLAlchemy的连接池配合好,或者隧道、MySQL的配置有疏漏。咱们一步步来搞定它:
1. 确保SSH隧道在SQLAlchemy连接前启动并保持活跃
很多时候问题出在隧道还没完全建立,SQLAlchemy就尝试连接了,或者隧道提前关闭了。用SSHTunnelForwarder的上下文管理器可以很好地管控隧道的生命周期:
from flask import Flask from flask_sqlalchemy import SQLAlchemy from sshtunnel import SSHTunnelForwarder app = Flask(__name__) # 配置并启动SSH隧道 with SSHTunnelForwarder( ("你的远程SSH服务器IP", 22), ssh_username="SSH登录用户名", ssh_password="SSH登录密码", # 如果用密钥登录,换成ssh_pkey="/path/to/your/private/key" remote_bind_address=("远程MySQL服务器的内网IP/域名", 3306) ) as tunnel: # 把SQLAlchemy的连接地址指向隧道转发到本地的端口 app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://<DB用户名>:<DB密码>@localhost:{tunnel.local_bind_port}/<数据库名>" # 关键:添加连接池配置,避免闲置连接失效 app.config['SQLALCHEMY_POOL_RECYCLE'] = 300 # 5分钟后自动回收闲置连接 app.config['SQLALCHEMY_POOL_PRE_PING'] = True # 获取连接前先ping,确保连接有效 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 关闭不必要的跟踪,节省资源 db = SQLAlchemy(app) # 测试连接是否正常 try: db.session.execute("SELECT 1") print("远程数据库连接成功!") except Exception as e: print(f"连接失败:{str(e)}")
2. 调整SQLAlchemy连接池参数
远程环境下,MySQL服务器或SSH隧道通常会关闭长时间闲置的连接。上面代码里的两个参数就是用来解决这个问题的:
SQLALCHEMY_POOL_RECYCLE:强制SQLAlchemy在指定秒数后回收连接,避免被远程端断开SQLALCHEMY_POOL_PRE_PING:每次从连接池拿连接前,先执行一个ping操作,确保连接是活的,失效的话会自动重新创建
3. 检查远程MySQL的权限配置
远程MySQL需要允许来自SSH服务器IP的访问(因为隧道是通过SSH服务器转发请求的)。登录到远程MySQL服务器,执行以下命令授权:
GRANT ALL PRIVILEGES ON <你的数据库名>.* TO '<DB用户名>'@'<SSH服务器的公网IP>' IDENTIFIED BY '<DB密码>'; FLUSH PRIVILEGES;
如果不确定SSH服务器的IP,也可以临时用%允许所有IP(不推荐生产环境这么做):
GRANT ALL PRIVILEGES ON <你的数据库名>.* TO '<DB用户名>'@'%' IDENTIFIED BY '<DB密码>'; FLUSH PRIVILEGES;
4. 更新sshtunnel到最新版本
旧版本的sshtunnel可能存在连接稳定性问题,执行下面的命令更新:
pip install --upgrade sshtunnel
这些步骤应该能解决你碰到的连接丢失问题,如果还有疑问,可以检查一下SSH服务器的防火墙规则,确保22端口对外开放,同时远程MySQL的3306端口允许SSH服务器访问。
内容的提问来源于stack exchange,提问作者drew kroft
相关产品推荐
相关产品推荐

