Lambda Node.js 16.X无服务器架构下PROTOCOL_CONNECTION_LOST错误解决
解决Lambda Node.js 16.X中mysql2的PROTOCOL_CONNECTION_LOST错误
错误详情
{ "errorType": "Error", "errorMessage": "Connection lost: The server closed the connection.", "code": "PROTOCOL_CONNECTION_LOST", "message": "Connection lost: The server closed the connection.", "stack": [ "Error: Connection lost: The server closed the connection.", " at PromisePoolConnection.query (/opt/nodejs/node_modules/mysql2/promise.js:93:22)", " at /var/task/index.js:1092:25", " at processTicksAndRejections (node:internal/process/task_queues:96:5)", " at async Runtime.handler (/var/task/index.js:1802:17)" ] }
解决方案
- 不要复用长期连接,每次请求创建并销毁连接
Lambda执行环境可能被复用,但数据库会主动关闭闲置连接(默认8小时)。如果代码复用旧连接,就会触发该错误。改成每次请求创建新连接,用完立即关闭:
const mysql = require('mysql2/promise'); exports.handler = async (event) => { let connection; try { connection = await mysql.createConnection({ host: '你的数据库地址', user: '数据库用户名', password: '数据库密码', database: '数据库名' }); const [rows] = await connection.query('SELECT * FROM your_table'); return { statusCode: 200, body: JSON.stringify(rows) }; } catch (err) { return { statusCode: 500, body: err.message }; } finally { if (connection) await connection.end(); } };
- 使用连接池并配置合理的闲置超时
若使用连接池,设置比数据库闲置超时更短的idleTimeout,同时在使用前检查连接有效性:
const mysql = require('mysql2/promise'); const pool = mysql.createPool({ host: '你的数据库地址', user: '数据库用户名', password: '数据库密码', database: '数据库名', waitForConnections: true, connectionLimit: 10, idleTimeout: 300000, // 5分钟,短于数据库默认的8小时 queueLimit: 0 }); exports.handler = async (event) => { let connection; try { connection = await pool.getConnection(); await connection.ping(); // 检查连接是否可用 const [rows] = await connection.query('SELECT * FROM your_table'); return { statusCode: 200, body: JSON.stringify(rows) }; } catch (err) { if (err.code === 'PROTOCOL_CONNECTION_LOST' && connection) { connection.destroy(); connection = await pool.getConnection(); const [rows] = await connection.query('SELECT * FROM your_table'); return { statusCode: 200, body: JSON.stringify(rows) }; } return { statusCode: 500, body: err.message }; } finally { if (connection) connection.release(); } };
检查数据库服务器配置
- 查询数据库的闲置超时设置:
SHOW VARIABLES LIKE '%timeout%';,确保wait_timeout和interactive_timeout值合理,避免过早关闭连接。 - 确认Lambda的VPC配置正确,安全组和防火墙规则允许Lambda与数据库通信,没有网络中断问题。
- 查询数据库的闲置超时设置:
添加连接重试逻辑
遇到连接丢失错误时自动重试1-2次,提升稳定性:
const mysql = require('mysql2/promise'); const pool = mysql.createPool({ /* 连接池配置 */ }); async function executeQuery(query, retries = 2) { let connection; try { connection = await pool.getConnection(); await connection.ping(); const [rows] = await connection.query(query); return rows; } catch (err) { if (err.code === 'PROTOCOL_CONNECTION_LOST' && retries > 0) { if (connection) connection.destroy(); return executeQuery(query, retries - 1); } throw err; } finally { if (connection) connection.release(); } } exports.handler = async (event) => { try { const rows = await executeQuery('SELECT * FROM your_table'); return { statusCode: 200, body: JSON.stringify(rows) }; } catch (err) { return { statusCode: 500, body: err.message }; } };
内容的提问来源于stack exchange,提问作者Aasai priyan
相关产品推荐
相关产品推荐

