Node.js连接Docker部署的MySQL出现PROTOCOL_CONNECTION_LOST错误求助
修复方案:PROTOCOL_CONNECTION_LOST 数据库连接断开问题
核心问题分析
- 端口配置错误:你的
script.js中把数据库端口设为2025,但这是phpMyAdmin的映射端口,MySQL容器的宿主机映射端口是6033(对应容器内部3306)。 - Host未正确配置:Node.js运行环境不同,Host值需对应调整——宿主机运行用
localhost,Docker容器内运行用MySQL服务名db。 - 单连接模式缺陷:
createConnection创建的单连接易被MySQL自动断开(尤其是空闲时),且connectionLimit是连接池专属参数,单连接模式下无效。
标准修复步骤
场景1:Node.js在宿主机(Docker外部)运行
修改script.js,修正端口、Host,并改用连接池(推荐,自动管理连接生命周期):
var mysql = require("mysql"); // 用连接池替代单连接,避免闲置断开 var pool = mysql.createPool({ host: "localhost", // 宿主机访问Docker内MySQL用localhost user: "db_user", password: "db_user_pass", database: "app_db", port: 6033, // MySQL容器的宿主机映射端口 connectionLimit: 10, // 合理设置连接池大小,无需过大 waitForConnections: true, queueLimit: 0 }); // 测试连接 pool.getConnection(function(err, connection) { if (err) throw err; console.log("Connected!"); // 用完连接后释放回池,避免资源泄漏 connection.release(); }); // 监听连接错误,自动处理重连逻辑 pool.on('error', function(err) { console.error('数据库连接池错误:', err); if (err.code === 'PROTOCOL_CONNECTION_LOST') { console.log('连接已断开,连接池将自动尝试重连'); } });
场景2:Node.js在Docker容器中运行(加入docker-compose管理)
- 更新
docker-compose.yml,添加Node.js服务并配置健康检查:
version: '3' services: db: image: mysql:5.7 container_name: db environment: MYSQL_ROOT_PASSWORD: my_secret_password MYSQL_DATABASE: app_db MYSQL_USER: db_user MYSQL_PASSWORD: db_user_pass ports: - "6033:3306" volumes: - dbdata:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] timeout: 20s retries: 10 phpmyadmin: image: phpmyadmin/phpmyadmin container_name: pma links: - db environment: PMA_HOST: db PMA_PORT: 3306 PMA_ARBITRARY: 1 restart: always ports: - 2025:80 depends_on: db: condition: service_healthy node-app: build: . # 假设项目根目录存在Dockerfile container_name: node-app ports: - "3000:3000" depends_on: db: condition: service_healthy volumes: - .:/app # 开发环境挂载代码目录,支持热更新 volumes: dbdata:
- 修改
script.js,使用Docker服务名作为Host:
var mysql = require("mysql"); var pool = mysql.createPool({ host: "db", // Docker内部直接用MySQL服务名访问容器 user: "db_user", password: "db_user_pass", database: "app_db", port: 3306, // 容器内部MySQL原生端口,无需映射端口 connectionLimit: 10 }); pool.getConnection(function(err, connection) { if (err) throw err; console.log("Connected!"); connection.release(); }); pool.on('error', function(err) { console.error('数据库连接池错误:', err); });
- 项目根目录创建
Dockerfile示例:
FROM node:19.3.0 WORKDIR /app COPY package*.json ./ RUN npm install COPY . . CMD ["npm", "start"]
额外优化建议
- 配置MySQL健康检查:确保Node.js服务在MySQL完全启动后再启动,避免启动初期连接失败。
- 避免单连接依赖:连接池会自动处理连接复用、重连,比单连接更稳定,适合生产环境。
内容的提问来源于stack exchange,提问作者Kishan Bhensadadiya
相关产品推荐
相关产品推荐

