You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sequelize可正常连接MySQL但mysql2(rate-limiter-flexible)超时问题排查

Node.js后端MySQL连接异常问题:Sequelize正常但mysql2+rate-limiter-flexible超时

问题背景

  • 使用Digital Ocean托管的MySQL集群
  • Sequelize可成功连接数据库,模型与查询均正常工作
  • 通过rate-limiter-flexible库使用mysql2包时,出现connect ETIMEDOUT错误

正常连接的Sequelize代码

import { Sequelize } from "sequelize";
import { production } from "./config.js";

const sequelize = new Sequelize(
  production.DB,
  production.USERNAME,
  production.PASSWORD,
  {
    host: production.HOST,
    port: production.PORT,
    dialect: "mysql",
    dialectOptions: {
      charset: "utf8",
    },
    timezone: "+03:00",
  }
);

sequelize.authenticate()
  .then(() => console.log("Connection has been established successfully."))
  .catch((err) => console.error("Unable to connect to the database:", err));

出现超时的mysql2+rate-limiter-flexible代码

import { RateLimiterMySQL } from "rate-limiter-flexible";
import mysql from "mysql2";
import { production } from "../config/config.js";

const mysqlConfig = {
  host: production.HOST,
  user: production.USERNAME,
  password: production.PASSWORD,
  database: production.DB,
  port: production.PORT,
  // connectTimeout: 10000 // even tried increasing this
};

const setup = async () => {
  const pool = mysql.createPool(mysqlConfig);

  const createBlockTableSQL = `
    CREATE TABLE IF NOT EXISTS rate_limit_block (
      ip_address varchar(100) NOT NULL,
      points int(11) unsigned NOT NULL DEFAULT '0',
      expire BIGINT,
      PRIMARY KEY (ip_address)
    )
  `;

  return new Promise((resolve, reject) => {
    pool.query(createBlockTableSQL, (err) => {
      if (err) return reject(err);

      try {
        const blockLimiter = new RateLimiterMySQL({
          storeClient: pool,
          tableName: "block",
          tablePrefix: "rate_limit_",
          points: 20,
          duration: 60,
          blockDuration: 60 * 60 * 24,
          storeType: "mysql",
        });

        resolve({ blockLimiter });
      } catch (error) {
        reject(error);
      }
    });
  });
};

错误信息

Error: connect ETIMEDOUT
    at PoolConnection._handleTimeoutError (node_modules/mysql2/lib/connection.js:205:17)
    at listOnTimeout (node:internal/timers:581:17)
    at process.processTimers (node:internal/timers:519:7)

额外上下文

  • Sequelize与mysql2使用完全相同的连接配置
  • Digital Ocean数据库已允许开发IP及通配符%访问
  • 未达连接限制,且凭据在MySQL Workbench和Sequelize中均可用
  • 已尝试增大mysql2的connectTimeout但无效

疑问

  1. 为何Sequelize可正常连接,而mysql2(通过rate-limiter-flexible)超时?
  2. 是否遗漏了mysql2针对Digital Ocean托管数据库的特定连接选项?
  3. 该问题是否与rate-limiter-flexible内部使用连接池的方式有关?
  4. 如何进一步调试以确定问题出在Digital Ocean端还是连接池初始化方式?

内容的提问来源于stack exchange,提问作者Rawand ofj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 12:03:15