У меня эта проблема уже больше пары месяцев, и я до сих пор не могу понять, как ее исправить. Кажется, что я испытываю большое количество соединений с нашей базой данных, и я предполагаю, что это потому, что наши соединения не закрываются должным образом, что заставляет их зависать в течение длительных периодов времени. В свою очередь это приводит к большим накладным расходам, которые иногда приводят к тому, что наше веб-приложение обрабатывает sh. В настоящее время приложение запускает пакет promise-mysql
npm для создания соединения и запроса к базе данных. Наше веб-приложение использует socketio
для запроса этих соединений с нашей базой данных * 1003. *
Я работаю с существующим кодом, который был здесь до меня, поэтому я не настроил его таким образом. Это немного сбивает с толку отладку этой проблемы, потому что я не очень знаком с тем, как закрываются соединения после успешного / неудачного запроса.
При регистрации ошибок с нашего сервера я получаю сообщения как это:
db error { Error: Connection lost: The server closed the connection.
at Protocol.end (/home/ec2-user/myapp/node_modules/mysql/lib/protocol/Protocol.js:113:13)
at Socket.<anonymous> (/home/ec2-user/myapp/node_modules/mysql/lib/Connection.js:109:28)
at Socket.emit (events.js:185:15)
at Socket.emit (domain.js:422:20)
at endReadableNT (_stream_readable.js:1106:12)
at process._tickCallback (internal/process/next_tick.js:178:19) fatal: true, code: 'PROTOCOL_CONNECTION_LOST' }
(Не уверен, имеет ли это какое-либо отношение к большому количеству соединений, которые я вижу или нет)
Я недавно изменил wait_timeout
и interactive_timeout
до 5000
в MySql
, что намного ниже, чем значение по умолчанию 28800
, но установка его на это предотвратила частое падение приложения.
Это код для создания соединения с базой данных:
import mysql from 'promise-mysql';
import env from '../../../env.config.json';
const db = async (sql, descriptor, serializedParameters = []) => {
return new Promise( async (resolve, reject) => {
try {
const connection = await mysql.createConnection({
//const connection = mysql.createPool({
host: env.DB.HOST,
user: env.DB.USER,
password: env.DB.PASSWORD,
database: env.DB.NAME,
port: env.DB.PORT
})
if (connection && env.ENV === "development") {
//console.log(/*"There is a connection to the db for: ", descriptor*/);
}
let result;
if(serializedParameters.length > 0) {
result = await connection.query(sql, serializedParameters)
} else result = await connection.query(sql);
connection.end();
resolve(result);
} catch (e) {
console.log("ERROR pool.db: " + e);
reject(e);
};
});
}
export default db;
И это пример того, как выглядят сокеты:
socket.on('updateTimeEntry', async (time, notes, TimeEntryID, callback) => {
try {
const results = await updateTimeEntry(time, notes, TimeEntryID);
callback(true);
//socket.emit("refreshJobPage", false, "");
}
catch (error) {
callback(false);
}
});
socket.on('selectDatesFromTimeEntry', (afterDate, beforeDate, callback) => {
const results = selectDatesFromTimeEntry(afterDate, beforeDate).then((results) => {
//console.log('selectLastTimeEntry: ', results);
callback(results);
})
});
И это пример методов, которые вызываются из сокетов для установления соединения с база данных
import db from './database';
export const updateTimeEntry = (time, notes, TimeEntryID) => {
return new Promise(async (resolve, reject) => {
try {
const updateTimeEntry = `UPDATE mytable SET PunchOut = NOW(), WorkTimeTotal = '${time}', Notes = "${notes}" WHERE TimeEntryID = '${TimeEntryID}';`
const response = await db(updateTimeEntry, "updateTimeEntry");
resolve(response[0]);
} catch (e) {
console.log("ERROR TimeEntry.updateTimeEntry: " + e);
reject(e);
}
});
};
//Gets a List for Assigned Jobs
export const selectDatesFromTimeEntry = (afterDate, beforeDate) => {
return new Promise(async (resolve, reject) => {
try {
const selectDatesFromTimeEntry = `SELECT * FROM mytable.TimeEntry WHERE PunchIn >= '${afterDate}' && PunchIn < '${beforeDate}';`
//console.log("Call: " + selectDatesFromTimeEntry);
const response = await db(selectDatesFromTimeEntry, "selectDatesFromTimeEntry");
//console.log("Response: " + response);
resolve(response);
} catch (e) {
console.log("ERROR TimeEntry.selectDatesFromTimeEntry: " + e);
reject(e);
}
});
};
Я просто очень хочу понять, почему я замечаю такие большие затраты на соединения с базой данных, и что я могу сделать, чтобы решить эту проблему. Я действительно не хочу продолжать перезапускать мой сервер каждый раз, когда он выходит из строя, так что, надеюсь, я смогу найти некоторые ответы на это. Если у кого-то есть какие-либо предложения или они знают, что я могу изменить в своем коде, чтобы решить эту проблему, это мне очень поможет, спасибо!
РЕДАКТИРОВАТЬ
Это ошибки, которые я получаю от mysql
2020-04-30T11:12:40.214381Z 766844 [Note] Aborted connection 766844 to db: 'mydb' user: 'xxx' host: 'XXXXXX' (Got timeout reading communication packets)
2020-04-30T11:12:48.155598Z 766845 [Note] Aborted connection 766845 to db: 'mydb' user: 'xxx' host: 'XXXXXX' (Got timeout reading communication packets)
2020-04-30T11:15:53.167160Z 766848 [Note] Aborted connection 766848 to db: 'mydb' user: 'xxx' host: 'XXXXXX' (Got timeout reading communication packets)
РЕДАКТИРОВАТЬ Есть ли способ понять, почему некоторые из этих соединений зависают или бездействуют?