Как исправить слишком много в _connectionQueue пула? - PullRequest
0 голосов
/ 24 сентября 2019

Мой очень простой код Node.js не похож на работу пула соединений, как это должно быть._connectionQueue из Pool объект просто становится все длиннее и длиннее бесконечно, и приложение умирает.Я имею в виду, что он создает пул, и уже есть готовые соединения, но их нельзя использовать повторно или запросы на вставку слишком велики и быстры?Я не уверен ..

Я попытался добавить еще connectionLimit, например:

let state = { pool: null }
export const connect = () => {
  state.pool = mysql.createPool({
    connectionLimit: 200,
    host: process.env.DATABASE_HOST || 'localhost',
    user: process.env.DATABASE_USER || 'root',
    password: process.env.DATABASE_PASSWORD || 'password',
    database: process.env.DATABASE_NAME || 'database'
  })
}

export const get = () => state.pool

В основном задание этого сервера - подписка и вставка.Он подписывается на несколько тем MQTT и просто пытается вставить сообщения в RDB.Около 100 сообщений приходит каждую секунду, и этот код выглядит следующим образом.

mqttClient.on('message', function (topic, message) {

    if(topic.includes('sensor')){     

      try { 
        const data = JSON.parse(message.toString())

        if(validate(data.uuid)){
          const params = [data.a, data.b, data.c, ...]
          sensor.setStatus(params)
        }
      } catch(err){
        console.error(err)
      }

    }
}
export const setStatus = (params) => {

  const SQL = `INSERT INTO ...`

  db.get().query(SQL, params, (err, result) => {
    if (err) console.error(err)
  })
}

Затем я вижу это через chrome-devtools

Object
pool: Pool
config: PoolConfig {acquireTimeout: 10000, connectionConfig: ConnectionConfig, waitForConnections: true, connectionLimit: 200, queueLimit: 0}
domain: null
_acquiringConnections: []
_allConnections: (200) [PoolConnection, PoolConnection, …]
_closed: false
_connectionQueue: (11561) [ƒ, ƒ, ƒ, ƒ, …]
_events: {}
_eventsCount: 0
_freeConnections: []
_maxListeners: undefined
__proto__: EventEmitter
__proto__: Object

У меня естьпоместите console.log в setStatus следующим образом:

export const setStatus = (params) => {

  const SQL = `INSERT INTO ...`
  console.log(`allConnections=${db.get()._allConnections.length}, connectionQueue=${db.get()._connectionQueue.length}`)

  db.get().query(SQL, params, (err, result) => {
    if (err) console.error(err)
  })
}

и получите их.

allConnections=200, connectionQueue=29
allConnections=200, connectionQueue=30
allConnections=200, connectionQueue=31
allConnections=200, connectionQueue=32
allConnections=200, connectionQueue=33
allConnections=200, connectionQueue=34
...

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

1 Ответ

0 голосов
/ 24 сентября 2019

Похоже, вы создаете новый пул каждый раз, когда хотите выполнить запрос.Общая модель состоит в том, чтобы создать пул один раз при запуске приложения, а затем использовать соединения из этого пула по мере необходимости (один пул, много подключений).

Также, если вы используете простую модель БД, вы можете упростить доступв бассейн, сделав его глобальным.Ниже приведен альтернативный код, который вы можете попробовать:

app.js

const mysql = require('mysql');

const connection = mysql.createPool({
  host: process.env.DB_HOST || '127.0.0.1',
  user: process.env.DB_USER || 'local_user',
  password: process.env.DB_PASSWORD || 'local_password',
  database: process.env.DB_NAME || 'local_database'
});

global.db = connection;

modules.js

export const setStatus = (params) => {
  let SQL = `INSERT INTO ...`
  db.query(SQL, params, (err, result) => {
    if (err) console.error(err)
    console.log(result)
  })
}

Документация для дальнейшего ознакомления :: https://github.com/mysqljs/mysql#pooling-connections

Редактировать 1 - Журнал событий пула

db.on('acquire', function (connection) {
  console.log('Connection %d acquired', connection.threadId);
});

db.on('connection', function (connection) {
  console.log('Pool id %d connected', connection.threadId);
});

db.on('enqueue', function () {
  console.log('Waiting for available connection slot');
});

db.on('release', function (connection) {
  console.log('Connection %d released', connection.threadId);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...