簡體   English   中英

Node.js 應用程序中的 SequelizeConnectionError

[英]SequelizeConnectionError in Node.js application

我有一個奇怪的問題,不知道問題出在哪里。 我將不勝感激任何幫助。

我有Node.js應用程序,它在本地 windows 10 計算機上運行良好。 我在CentOS服務器中的 Docker 成功運行了這個應用程序。 此應用程序適用於遠程 MySQL 和 PostgreSQL 數據庫。 它幾天都正常工作,但昨天我發現我有錯誤。 應用程序無法再連接到遠程 MySQL 數據庫。 同時,如果我在本地計算機上運行應用程序或通過 DBeaver/dbForge 工具連接,我可以毫無問題地連接到遠程 MySQL 數據庫。

MySQL.js

const Sequelize = require('sequelize');

const sequelize = new Sequelize('database_name', 'username', 'password', {
    host: 'host',
    dialect: 'mysql'
});

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

module.exports = sequelize;

路線.js

const express = require('express');

const router = express.Router();

const sequelize = require('../configurations/MySQL');
const Sequelize = require('sequelize');

const passport = require('passport');
require('../configurations/password')(passport);

router.post('/search_by_name', passport.authenticate('jwt', {session: false}, null), function(req, res) {
    const token = getToken(req.headers);
    if (token) {
        sequelize.query("LONG SQL QUERY", {
            replacements: {
                name: req.body.name,
            },
            type: Sequelize.QueryTypes.SELECT
        }).then((locations) => {
            res.status(200).send(locations)
        }).catch((error) => {
            res.status(400).send(error);
        });
    } else {
        return res.status(401).send({
            status: false,
            description: "Unauthorized"
        });
    }
});

如您所見,我使用sequelize庫將應用程序連接到遠程 MySQL 數據庫。 我用來連接遠程 PostgreSQL 數據庫的同一個庫。 正如我之前所說,僅當我嘗試連接到 Docker 中的遠程 MySQL 數據庫時才會發生錯誤。Docker 中的 PostgreSQL 連接沒有錯誤。Docker.network 中是否可能存在該問題?

依賴項

"sequelize": "^4.42.0"
"mysql2": "^1.6.4"

我還認為問題的原因可能是因為很多池/連接和 sequelize 庫不會自動關閉它們。 這就是為什么我多次重啟 docker сontainer 希望證實這個理論的原因。 不幸的是錯誤並沒有消失。

你怎么想,會發生什么?

錯誤

Unable to connect to the database: { SequelizeConnectionError: connect ETIMEDOUT
    at Utils.Promise.tap.then.catch.err (/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:149:19)
    at tryCatcher (/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/node_modules/bluebird/js/release/promise.js:690:18)
    at _drainQueueStep (/node_modules/bluebird/js/release/async.js:138:12)
    at _drainQueue (/node_modules/bluebird/js/release/async.js:131:9)
    at Async._drainQueues (/node_modules/bluebird/js/release/async.js:147:5)
    at Immediate.Async.drainQueues [as _onImmediate] (/node_modules/bluebird/js/release/async.js:17:14)
    at processImmediate (timers.js:632:19)
  name: 'SequelizeConnectionError',
  parent:
   { Error: connect ETIMEDOUT
       at Connection._handleTimeoutError (/node_modules/mysql2/lib/connection.js:173:17)
       at listOnTimeout (timers.js:324:15)
       at processTimers (timers.js:268:5)
     errorno: 'ETIMEDOUT',
     code: 'ETIMEDOUT',
     syscall: 'connect',
     fatal: true },
  original:
   { Error: connect ETIMEDOUT
       at Connection._handleTimeoutError (/node_modules/mysql2/lib/connection.js:173:17)
       at listOnTimeout (timers.js:324:15)
       at processTimers (timers.js:268:5)
     errorno: 'ETIMEDOUT',
     code: 'ETIMEDOUT',
     syscall: 'connect',
     fatal: true }}

嘗試在新 Sequelize 時添加池選項。 參考文件

Sequelize 將在初始化時設置一個連接池,因此如果您從單個進程連接到數據庫,則理想情況下您應該只為每個數據庫創建一個實例。 如果您從多個進程連接到數據庫,則必須為每個進程創建一個實例,但每個實例的最大連接池大小應為“最大連接池大小除以實例數”。 因此,如果您希望最大連接池大小為 90,並且您有 3 個工作進程,則每個進程的實例的最大連接池大小應為 30。

const Sequelize = require('sequelize');

const sequelize = new Sequelize('database_name', 'username', 'password', {
    host: 'host',
    dialect: 'mysql',
    pool: {
      max: 15,
      min: 5,
      idle: 20000,
      evict: 15000,
      acquire: 30000
    },
});

module.exports = sequelize;

此外,您可以在此處查看更多選項

options.pool sequelize 連接池配置

options.pool.max默認值:5 池中的最大連接數

options.pool.min默認值:0 池中的最小連接數

options.pool.idle默認值:10000 連接在被釋放之前可以空閑的最長時間(以毫秒為單位)。 與 evict 結合使用以確保正常工作,有關更多詳細信息,請閱讀https://github.com/coopernurse/node-pool/issues/178#issuecomment-327110870

options.pool.acquire默認值:10000 該池在拋出錯誤之前嘗試獲取連接的最長時間(以毫秒為單位)

options.pool.evict默認值:10000 驅逐陳舊連接的時間間隔(以毫秒為單位)。 將其設置為 0 以禁用此功能。

options.pool.handleDisconnects默認值:true 控制池是否應自動處理連接斷開而不拋出錯誤

options.pool.validate驗證連接的函數。 與客戶通話。 默認函數檢查客戶端是一個對象,並且它的狀態沒有斷開

我建議檢查數據庫主機名。 請嘗試解析主機名,如果給出的是 IP 地址而不是域。 這將解決問題。

簡單來說,我想說的是,當您輸入某些配置錯誤時,就會出現這些類型的錯誤。 這些是 :

  1. 數據庫名稱
  2. 用戶名
  3. 密碼

所以請在你的congif.json文件中交叉驗證你的這些東西

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM