SequelizeConnectionError в приложении Node.js - PullRequest
0 голосов
/ 13 марта 2019

У меня странная проблема, и я не знаю, в каком месте проблема. Буду благодарен за любую помощь.

У меня есть Node.js приложение, которое прекрасно работает на локальном компьютере с Windows 10. Я успешно запускаю это приложение в Docker , который находится на сервере CentOS. Это приложение работает с удаленными базами данных MySQL и PostgreSQL. Он работал правильно несколько дней, но сегодня я замечаю, что у меня ошибка. Приложение больше не может подключаться к удаленной базе данных MySQL. В то же время я могу без проблем подключиться к этой удаленной базе данных MySQL, если я запускаю приложение на своем локальном компьютере или подключаюсь с помощью инструмента DBeaver / dbForge.

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;

routes.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. Как я уже говорил, ошибка возникает только тогда, когда я пытаюсь подключиться к удаленной базе данных MySQL в Docker. В Docker нет ошибки с соединением PostgreSQL. Возможно ли, что проблема внутри Docker / сети?

1024 * Зависимость *:

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

Я также подумал, что причина проблемы может быть в том, что из-за большого количества пулов / подключений библиотека секвелирования не закрывает их автоматически. Поэтому я несколько раз перезапускал контейнер с докером в надежде подтвердить теорию. К сожалению ошибка не исчезает.

Как вы думаете, что происходит?

Error

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 }}

1 Ответ

0 голосов
/ 13 марта 2019

Попробуйте добавить параметр пула, когда новый 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 продолжение конфигурации пула соединений

options.pool.max по умолчанию: 5 Максимальное количество соединений в пуле

options.pool.min по умолчанию: 0 Минимальное количество соединений в пуле

options.pool.idle default: 10000 Максимальное время в миллисекундах, что соединение может быть бездействующим до освобождения. Использовать с комбинация выселения для правильной работы, более подробно читайте https://github.com/coopernurse/node-pool/issues/178#issuecomment-327110870

options.pool.acquire default: 10000 Максимальное время в миллисекундах, этот пул попытается установить соединение перед выдачей ошибки

options.pool.evict по умолчанию: 10000 Интервал времени в миллисекундах, для удаления устаревших соединений. Установите 0, чтобы отключить эту функцию.

options.pool.handleDisconnects default: true Управляет разрешением пула Отключение соединения с ручкой происходит автоматически без ошибок

options.pool.validate Функция, которая проверяет соединение. Называется с клиентом. Функция по умолчанию проверяет, что клиент является объектом, и что его состояние не отключено

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...