Docker Compose部署React+Python+MySQL应用遇SSL协议违规连接断开
解决Docker Compose部署中MySQL连接频繁断开的2055错误
问题现象
前端通过Axios多次发起请求后,Python后端抛出MySQL连接错误:
"2055: Lost connection to MySQL server at 'database:3306', system error: 8 EOF occurred in violation of protocol (_ssl.c:2483)"
已尝试mysql-connector-python==8.0.30并设置ssl=false,问题未解决。
解决方案
1. 使用数据库连接池复用连接
每次请求新建连接会导致MySQL因连接数过载或闲置连接被回收而断开,改用连接池复用连接:
import mysql.connector from mysql.connector import pooling import os # 初始化全局连接池 db_pool = pooling.MySQLConnectionPool( pool_name="locatec_pool", pool_size=10, # 根据实际请求量调整大小 host=os.environ.get("database"), user="root", password="root", database="locatec", port=3306, auth_plugin='mysql_native_password', ssl_disabled=True # 明确禁用SSL ) # 从连接池获取连接 def get_db_connection(): return db_pool.get_connection()
注意:请求处理完成后需调用connection.close()将连接放回池,而非直接销毁。
2. 调整MySQL连接超时参数
MySQL默认的闲置连接回收阈值可能过短,修改Docker Compose的database服务参数:
database: image: mysql container_name: database restart: always ports: - '3306:3306' volumes: - ./init.sql:/docker-entrypoint-initdb.d/init.sql - ~/apps/mysql:/var/lib/locatec5 environment: MYSQL_ROOT_PASSWORD: root MYSQL_USER: test MYSQL_PASSWORD: test MYSQL_ROOT_HOST: '%' TIMEZONE: UTC command: --wait_timeout=28800 --interactive_timeout=28800 --max_connections=200 # 调整超时与最大连接数 networks: - locatec
也可挂载自定义my.cnf配置文件:
[mysqld] wait_timeout = 28800 interactive_timeout = 28800 max_connections = 200
在database服务的volumes中添加:
volumes: - ./my.cnf:/etc/mysql/conf.d/my.cnf # 原有volumes保留
3. 固定MySQL镜像版本,避免兼容性问题
使用mysql:latest可能因版本自动更新导致与mysql-connector-python不兼容,指定与连接器匹配的版本:
database: image: mysql:8.0.30 # 与mysql-connector-python版本一致 # 其他配置不变
4. 排查Docker网络稳定性
- 重启所有容器重置网络:
docker-compose down -v && docker-compose up -d - 查看MySQL容器日志,排查连接断开的具体原因:
重点关注docker logs databaseAborted connection类日志,确认是MySQL主动断开还是网络异常。
5. 添加连接重试机制
捕获连接错误,自动重试获取连接:
def get_db_connection(): try: return db_pool.get_connection() except mysql.connector.errors.OperationalError as e: # 连接失效时重新初始化连接池 global db_pool db_pool = pooling.MySQLConnectionPool( pool_name="locatec_pool", pool_size=10, host=os.environ.get("database"), user="root", password="root", database="locatec", port=3306, auth_plugin='mysql_native_password', ssl_disabled=True ) return db_pool.get_connection()
内容的提问来源于stack exchange,提问作者Óscar Contreras
相关产品推荐
相关产品推荐

