RDS MySQL 通过 Heroku 到 AWS 对等连接的连接超时

RDS MySQL Connection Timeout Over Heroku to AWS Peering Connection

我在尝试从 Heroku one-off dyno to a MySQL RDS instance over Heroku's Private Space Peering Connection. The error is a ETIMEDOUT error using the node mysql2 库建立连接时看到间歇性连接超时。它以大约 1/100 次尝试的频率发生,没有一天中时间的模式。还值得注意的是以下几点:

这些是我调查并排除的潜在问题:

当前 MySQL 连接配置使用默认的 10000 连接超时。我在不了解根本原因的情况下犹豫是否提出这个问题,因为 10 秒应该足以建立连接。下面是连接和断开连接的代码:

const mysql = require('mysql2/promise');

// Heroku dyno boots up via the scheduler add-on

const connection = await mysql.createConnection({
    timezone: '+00:00',
    dateStrings: ['DATE', 'DATETIME'],
    decimalNumbers: true,
    host: process.env.MYSQL_HOST,
    database: process.env.MYSQL_DATABASE,
    user: process.env.MYSQL_USER,
    password: process.env.MYSQL_PASSWORD,
    port: parseInt(process.env.MYSQL_PORT, 10),
    ssl: fs.readFileSync('...', 'utf8')
});

// Do some work

await connection.end();

// Heroku dyno is torn down

很难深入了解 Heroku 私有 space 方面的事情,因为它太抽象了,但是有人见过这种问题吗?

更新 1

能够在一次性 dynos 上安装一些工具,并且可以成功远程登录并连接 mysql 客户端,尽管从节点 mysql lib 超时。所以看起来节点 mysql2 库正在超时,而 运行 这些命令没有。为什么会这样?

# prints Connected to [HOST]. Escape character is '^]'.
$ echo -e '\x1dclose\x0d' | telnet ${process.env.MYSQL_HOST} ${process.env.MYSQL_PORT}

# prints 8.0.17
$ echo "SELECT VERSION() AS version" | mysql -h ${process.env.MYSQL_HOST} -u ${process.env.MYSQL_USER} -p${process.env.MYSQL_PASSWORD}

更新 2

当我们看到超时时,我已经梳理了 RDS ENI 的流日志,并且我看到流量来自遇到超时的机器的 IP。这确认来自 debug telnet <HOST> <PORT>mysql -h <HOST> ... 命令的流量正确通过。

这不是一个令人满意的答案,但考虑到 Heroku 的黑盒性质,这就是我们得到的全部。我们的数据库托管在与我们的 Heroku dynos 不同的区域。将它们置于同一个 AWS 区域解决了这个问题。