Docker中MySQL与Flask/Python连接自动断开的解决咨询
解决Docker中MySQL与Flask容器连接超时问题
一、修改MySQL配置,延长连接超时时间
MySQL默认的wait_timeout和interactive_timeout参数为28800秒(8小时),这正好匹配你遇到的断开时间。可以通过以下方式调整:
启动容器时添加参数:
启动MySQL容器时直接指定超时参数,比如设置为1天(86400秒):docker run -d \ --name mysql-container \ -e MYSQL_ROOT_PASSWORD=your-password \ -e MYSQL_DATABASE=your-db \ mysql:latest \ --wait-timeout=86400 \ --interactive-timeout=86400挂载自定义配置文件:
创建my.cnf配置文件:[mysqld] wait_timeout = 86400 interactive_timeout = 86400启动容器时挂载该文件到MySQL配置目录:
docker run -d \ --name mysql-container \ -e MYSQL_ROOT_PASSWORD=your-password \ -e MYSQL_DATABASE=your-db \ -v /本地路径/my.cnf:/etc/mysql/conf.d/my.cnf \ mysql:latest
二、代码层面优化连接管理,处理重连
即使调整了MySQL超时,仍可能因网络波动等情况导致连接断开,且直接调用cnx.close()或cnx.reconnect()可能因无效连接阻塞,需通过以下方式优化:
1. 设置连接超时参数
创建连接时指定connect_timeout和socket_timeout,避免操作无限阻塞:
cnx = mysql.connector.connect( host='mysql-container', # 使用容器名或自定义网络IP user='your-user', password='your-password', database='your-db', connect_timeout=10, # 连接超时10秒 socket_timeout=30 # 读写操作超时30秒 )
2. 封装连接验证与重连逻辑
不要长期持有单一连接,每次操作前验证连接有效性,无效则重新创建:
import mysql.connector from mysql.connector import Error _db_connection = None def get_valid_connection(): global _db_connection try: if _db_connection and _db_connection.is_connected(): # 执行简单查询验证连接可用性 cursor = _db_connection.cursor() cursor.execute("SELECT 1") cursor.close() return _db_connection except Error: # 连接无效,尝试关闭旧连接 if _db_connection: try: _db_connection.close() except: pass # 关闭失败无需额外处理 # 创建新连接 _db_connection = mysql.connector.connect( host='mysql-container', user='your-user', password='your-password', database='your-db', connect_timeout=10, socket_timeout=30 ) return _db_connection
3. 使用连接池(推荐)
mysql.connector提供连接池功能,自动管理连接的创建、复用与销毁,无需手动处理重连:
from mysql.connector import pooling # 初始化连接池 db_pool = pooling.MySQLConnectionPool( pool_name="mypool", pool_size=5, # 根据并发需求调整大小 host='mysql-container', user='your-user', password='your-password', database='your-db', connect_timeout=10, socket_timeout=30 ) # 获取可用连接 def get_pool_connection(): try: cnx = db_pool.get_connection() # 验证连接有效性 cursor = cnx.cursor() cursor.execute("SELECT 1") cursor.close() return cnx except Error: # 连接无效,销毁后重新获取 cnx.close() return db_pool.get_connection()
4. 解决阻塞问题
当连接已被MySQL端断开,本地连接对象处于半开状态,直接调用close()或reconnect()可能无限阻塞。通过设置socket_timeout,此类操作会在超时后抛出异常,捕获后重新创建连接即可。
内容的提问来源于stack exchange,提问作者chiru player
相关产品推荐
相关产品推荐

