Создавать все функции как asyn c - плохая практика с mysql knex - PullRequest
0 голосов
/ 14 апреля 2020

Я использовал knex. js (с подключением подчиненного и ведущего устройства) в узле для подключения mysql.

Мой код работает нормально для 150 пользователей, но когда количество одновременно работающих пользователей увеличивается, использование кучи в PM2 также достигает 100% или выше, и сервер перестает отвечать или реагирует очень медленно.

The * Использование процессора 1037 * (5 * большой экземпляр aws ec2 с 8-ядерным процессором и 32 ГБ ОЗУ) составляет 12-20%.

Приложение отвечает за миллисекунды аутентификацией JWT и pm2.

Там Есть много запросов, которые зависят от предыдущего результата запроса, поэтому я создал все функции как asyn c.

Проблемные c точка:

В каждый час, слот открыт для всех пользователей (около 150 000) для редактирования их контента (около 3 тыс. в режиме реального времени).

Временное решение, которое я сделал:

Разрешение кластера внедрения моя проблема, но при сбое кластера не закрывается соединение с БД.

Мои сомнения:

Когда приложение работает с кластером нормально, почему приложение не работает без кластер в той же конфигурации включено?

async function authorize(req, res) {
  //decode aes-128 request
  let body = await helper.get_decoded_request(req);
  if (!body) {
    return res.status(200).json(await helper.error("Error occurs while decoding."));
  }
  const schema = joi.object({
    "client_id": joi.string().min(1).required(),
    "client_secret": joi.string().min(1).required()
  });
  try {
    await schema.validateAsync(body);
  }
  catch (err) {
    return res.status(200).json(await helper.error("Please send the valid request"));
  }

  try {
    //data base update and add function that writen in other file
    await user.update_user(data);
    await match.add_transaction(data);
  } catch (err) {
    return res.status(200).json(await helper.error("Please send the valid request"));
  }

  return res.status(200).json(await helper.success("Token added successfully.", jsontoken));
}

Код файла модели:

const { read_db, write_db } = require("./database");
async function add_transaction(data) {
  return await write_db.insert(data).table("users");
}

Файл базы данных:

var knex = require("knex");
const read_db = knex({
  client: "mysql",
  connection: {
    database: process.env.SLAVE_MYSQL_DB,
    host: process.env.SLAVE_MYSQL_HOST,
    port: process.env.SLAVE_MYSQL_PORT,
    user: process.env.SLAVE_MYSQL_USER,
    password: process.env.MYSQL_PASSWORD
  },
  pool: { min: 1, max: 10 }
});
const write_db = knex({
  client: "mysql",
  connection: {
    database: process.env.MYSQL_DB,
    host: process.env.MYSQL_HOST,
    port: process.env.MYSQL_PORT,
    user: process.env.MYSQL_USER,
    password: process.env.MYSQL_PASSWORD
  },
  pool: { min: 1, max: 10 }
});
module.exports = { read_db, write_db };

1 Ответ

1 голос
/ 15 апреля 2020

Недостаточно информации, чтобы дать какие-либо ответы о root причине проблемы, но, возможно, эти общие шаги, как начать решение проблемы, помогают.

Первая и самая важная часть - репликация замедление локально и запустите ваше приложение в профилировщике, чтобы выяснить, какие части кода фактически занимают весь этот процессор. Запуск вашего приложения с node --inspect позволяет вам профилировать выполнение приложения в Chrome браузере-профилировщике.

Также звучит так, как будто вы запускаете только один процесс узла, так что довольно странно, как вы возможность использовать 100% CPU из всех 8 ядер с довольно низким количеством пользователей (менее 1000?) ... Одна вещь, которая приходит мне в голову, это то, что если вы проверяете, например, пароль ha sh при каждом запросе пользователя, он может на самом деле начать использовать много процессора очень быстро.

Если это действительно проблема, которую вы могли бы реализовать, например, JSON Поддержка Web Token для вашего приложения, где пароль используется только для получения токена доступа, который затем очень быстро проверяется по сравнению с аутентификацией по паролю. .

Когда ваше базовое c приложение работает нормально, вам следует задуматься о том, как запустить несколько процессов сервера на одном экземпляре, чтобы лучше использовать все ядра ЦП.

РЕДАКТИРОВАТЬ:

Похоже, что 12-20% 5-ядерных экземпляров - это около 100% одноядерных. Таким образом, ваше приложение, кажется, насыщает процессор.

Об использовании кучи: если вы профилируете приложение, вы сможете увидеть, является ли сборщик мусора, который начинает останавливать приложение.

Одной из причин может быть то, что вы на самом деле создаете слишком много тра sh, что в какой-то момент начинает ухудшать производительность. Вы также можете попробовать, если, например, немного увеличит размер кучи по умолчанию с 1,7 ГБ до 8 ГБ node --max-old-space-size=8092.

В дополнение к сборке мусора, например, если вы возвращаете десятки тысяч строк из БД, просто анализируя их до javascript объекты могут насыщать процессор. Таким образом, профилирование - все еще правильный способ попытаться выяснить, что происходит. Парсинг, особенно дат, по умолчанию очень медленный в knex (когда они конвертируются в Date объекты).

...