我正在运行一个通过 node-mysql 模块连接到 MySQL 的节点服务器。连接和查询 MySQL 最初运行良好,没有任何错误,但是,让 Node 服务器空闲几个小时后的第一个查询会导致错误。该错误是熟悉的
read ECONNRESET
,来自node-mysql模块的深处。
堆栈跟踪(请注意,跟踪的三个条目属于我的应用程序的错误报告代码):
Error
at exports.Error.utils.createClass.init (D:\home\site\wwwroot\errors.js:180:16)
at new newclass (D:\home\site\wwwroot\utils.js:68:14)
at Query._callback (D:\home\site\wwwroot\db.js:281:21)
at Query.Sequence.end (D:\home\site\wwwroot\node_modules\mysql\lib\protocol\sequences\Sequence.js:78:24)
at Protocol.handleNetworkError (D:\home\site\wwwroot\node_modules\mysql\lib\protocol\Protocol.js:271:14)
at PoolConnection.Connection._handleNetworkError (D:\home\site\wwwroot\node_modules\mysql\lib\Connection.js:269:18)
at Socket.EventEmitter.emit (events.js:95:17)
at net.js:441:14
at process._tickCallback (node.js:415:13)
此错误发生在我的云节点服务器和 MySQL 服务器以及两者的本地设置上。
我的问题:
此问题是否似乎是由于连接生命周期限制而导致 Node 与我的 MySQL 服务器的连接断开?
使用连接池时,node-mysql 应该优雅地处理断开连接并将其从池中删除。是不是在我查询之前才知道断开连接,从而导致错误不可避免?
考虑到我在其他 StackOverflow 帖子中经常看到“read ECONNRESET”错误,我是否应该从 MySQL 的其他地方寻找来诊断问题?
更新:经过更多浏览,我认为我的问题与这个问题重复。看来他的连接也断开了,但没有人建议如何保持连接处于活动状态,或者如何解决除了第一次查询失败之外的错误。
我在 他们的 Github 页面上联系了 node-mysql 人员,并得到了一些确定的答案。
MySQL 确实会修剪空闲连接。 MySQL 有一个变量“wait_timeout”,用于设置超时前的秒数,默认值为 8 小时。我们可以将默认值设置得比该值大得多。使用
show variables like 'wait_timeout';
查看您的超时设置,然后使用 set wait_timeout=28800;
进行更改。根据这个问题,node-mysql 在此类断开连接后不会修剪池连接。模块开发人员建议使用心跳来保持连接处于活动状态,例如每隔一段时间调用
SELECT 1;
。他们还建议使用 node-pool 模块 及其idleTimeoutMillis 选项来自动修剪空闲连接。如果在建立单个重用连接时发生这种情况,可以通过建立连接池来避免。
例如,如果你正在做这样的事情......
var db = require('mysql')
.createConnection({...})
.connect(function(err){});
改为这样做...
var db = require('mysql')
.createPool({...});
此问题是否似乎是由于连接生命周期限制而导致 Node 与 MySQL 服务器的连接断开?
是的。服务器已关闭其连接端。
使用连接池时,node-mysql 应该优雅地处理断开连接并将其从池中删除。是不是在我进行查询之前才意识到断开连接,从而使错误不可避免?
正确,但它应该在内部处理错误,而不是将其传回给您。这似乎是node-mysql 中的一个错误。举报吧。
考虑到我在其他 StackOverflow 帖子中经常看到“read ECONNRESET”错误,我是否应该从 MySQL 的其他地方寻找来诊断问题?
这要么是节点 MySQL 连接池实现中的错误,要么是您没有正确配置它来检测故障。
我也面临同样的问题。显然,发生这种情况是因为我的 api 中引用的表上已触发其中一个后端进程。
这导致表进入锁定等待状态,并且我的查询请求因连接重置而失败。虽然我想知道为什么我没有收到锁定等待错误。
最近,我在 MySQL 和 NestJS API 方面遇到了类似的问题。我的应用程序随机记录这样的错误:
[Nest] 1 - 12/05/2023, 11:53:56 AM ERROR [ExceptionsHandler] read ECONNRESET
QueryFailedError: read ECONNRESET
at Query.onResult (/usr/api/src/node_modules/typeorm/driver/mysql/MysqlQueryRunner.js:158:37)
at PoolConnection._notifyError (/usr/api/src/node_modules/mysql2/lib/connection.js:228:21)
at PoolConnection._handleFatalError (/usr/api/src/node_modules/mysql2/lib/connection.js:183:10)
at PoolConnection._handleNetworkError (/usr/api/src/node_modules/mysql2/lib/connection.js:196:10)
at Socket.emit (node:events:517:28)
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
通过减少MySQL数据库上的wait_timeout和interactive_timeout来解决:
set global wait_timeout = 1000;
set global interactive_timeout = 1000;