错误:Node.js MYSQL 模块中的握手不活动超时

Posted

技术标签:

【中文标题】错误:Node.js MYSQL 模块中的握手不活动超时【英文标题】:Error: Handshake inactivity timeout in Node.js MYSQL module 【发布时间】:2016-06-03 20:48:31 【问题描述】:

我正在使用node-mysql 和大多数查询。在职的。一些查询不起作用。 我尝试了每个版本的 Node(从 0.5...)直到(5.6.0),我也尝试了(4.0)和(4.1),没有任何帮助。

我尝试过手动更改,但没有成功。我试图将sequence 文件更改为:this._idleTimeout = -1;,但没有帮助。

我阅读了问题和 GitHub,但没有任何帮助。

我可以尝试自己修复它,但我需要更多信息。超时在哪里,为什么?什么时候?这种类型的消息是什么?超时从何而来?

MYSQL_ERROR      [Error: Handshake inactivity timeout]  
code: 'PROTOCOL_SEQUENCE_TIMEOUT',   fatal: true,   
timeout: 10000   

【问题讨论】:

我认为您是多次查询而不是使用单个查询,因为执行时间取决于触发的查询数量。如果您触发单个查询,则执行速度会很快,并且不会出现此错误。 对于其他发现此问题的人,如果您尝试使用无效的登录凭据创建连接/池(或者如果您传递的端口号与您的 mysql 端口不匹配,则此错误也会显示,通常是 3306)。 【参考方案1】:

好的,超时来自 Protocol.js 文件 line:162。如果您检查 node-mysql,您会看到它是一个用于查询的变量“超时”。如果您将超时设置为远高于默认值 10000,则错误应该会消失。一个例子是

pool = require('mysql').createPool(
    connectionLimit : 1000,
    connectTimeout  : 60 * 60 * 1000,
    acquireTimeout  : 60 * 60 * 1000,
    timeout         : 60 * 60 * 1000,
    host            : process.env.DB_HOST,
    user            : process.env.DB_USERNAME,
    password        : process.env.DB_PASSWORD,
    database        : process.env.DB_DATABASE
);

您还可以在 Sequence.js 文件 (node_modules/mysql/lib/protocol/sequences/Sequence.js) 中编辑超时时间

this._timeout  = 100000;

【讨论】:

"acquireTimeout" 上述代码示例中的拼写错误。 有时会因为无效的凭证而发生 我需要在我们的系统中执行此操作,因为它有时非常繁忙,延迟可能长达 30 秒。我们正在运行大量查询,有时它们会同时访问服务器。我一直在扩展 mysql 实例,但基本实例和副本之间仍然存在状态问题。 在 sequence.js 文件中我更改了时间限制,但没有工作。您能否提一下在 protocol.js 文件中我们必须提到此凭据的位置【参考方案2】:

对于那些在AWS 上部署并遇到此错误的用户,您需要更改您的数据库/集群和add an inbound rule 的安全组,其中source 是您的安全组实例/秒

入站规则应如下所示:

Type: MySQL/Aurora
Protocol: TCP (default)
Port: 3306 (default)
Source: <security group of instance>
Description: <optional>

【讨论】:

【参考方案3】:

如果您使用亚马逊的服务,我可以通过更改安全设置中允许的 IP 地址通过更改打开的连接端口来解决此问题。

【讨论】:

嗨凯文。你的意思是子网规则对吧?因为我已经允许来自我的 EC2 的 IP,但仍然收到此错误。它很少见。【参考方案4】:

.end() 是非阻塞的,但这可能会导致您的代码遇到与我相同的问题 - 我只是调用 .end() 而不等待操作实际完成。

要真正等待连接结束,您不能只等待 dbConn.end(),因为 .end() 不会返回承诺。您需要的是创建一个承诺并返回它。像下面这样:

来自

connection.end();

到这里

connection.end(error => error ? reject(error) : resolve());

对于池使用

connection.release();

到这里

connection.release(error => error ? reject(error) : resolve());

【讨论】:

我相信你的分析是正确的。测试快速击中数据库时,我遇到了不活动超时。实际时间很短,大约 150 毫秒。你是如何创建 Promise 的?你能解释一下你对 end() 的回答吗?【参考方案5】:

对于那些部署在 aws 和 heroku 上的人!输入 rds db instance settigns 并更改入站规则 --> source: any..

Heroku 不提供特定的 IP,请记住!

【讨论】:

在运行数据库时,允许任何来源都是相当高的风险。 我只是在这方面做了一些额外的阅读,基本上这你如何做的一部分,但要安全地做到这一点,有几个额外的步骤,解释here :***.com/a/42558720/340141 @ThomasRedstone 非常感谢,也许这是通过额外步骤将 heroku 与 RDS 连接起来的正确方法【参考方案6】:

对我来说,它是更正“选择”语句以选择检查 ID 列(主键)的位置,而不是它类型为 varchar 的列,例如: 不工作

select from users where userName = 'aa';

工作

select from users where userID = 1;

【讨论】:

【参考方案7】:

对于连接到 Amazon RDS 和 EC2 的用户,更改 RDS 和 EC2 实例的入站规则。 即 RDS 应该允许新的 IPv4,EC2 应该允许 MySQL/Aurora。

【讨论】:

以上是关于错误:Node.js MYSQL 模块中的握手不活动超时的主要内容,如果未能解决你的问题,请参考以下文章

使用池的node.js mysql中的错误处理和丢失连接

找不到模块“mysql”node.js

Node.js MySQL 模块中的 mysql.createConnection 和 mysql.createPool 有啥区别?

使用Nodejs的mysql模块连接MySql数据库出现以下错误

Node.JS、Socket.IO 和集群中的 WebSocket 握手不起作用

Node.js 的 MySQL 库中的错误