#mysql #node.js #express #google-cloud-sql
#mysql #node.js #выразить #google-cloud-sql
Вопрос:
Я прочитал всю документацию по объединению в mysqljs, и мне все еще не хватает некоторого контекста. Мой счет за CloudSQL только что вернулся и напомнил мне, что мой старый метод имеет серьезные недостатки. Я ищу некоторый контекст о том, как обрабатывать объединение MySQL в NodeJS для CRM, который выполняет множество SQL-запросов.
Мой старый метод подключения:
//* SELECT BY ID
app.post(`/api/v1/select/id`, (req, res) => {
let did = req.body.did;
let host = req.body.host;
let user = req.body.user;
let password = req.body.password;
let schema = req.body.schema;
let columns = accountColumns();
let connection = mysql.createConnection({
host: host,
user: user,
password: password,
database: schema,
port: 3306,
});
if (connection.state === "disconnected") {
connection.connect();
}
let selectStatement = `SELECT * FROM mydb.schema WHERE id = ${did};`;
connection.query(selectStatement, (err, results) => {
if (err) { throw err }
else {
res.send(results);
}
});
});
//* SELECT BY STATUS
app.post('/api/v1/status', (req, res) => {
let status= req.body.status;
let host = req.body.host;
let user = req.body.user;
let password = req.body.password;
let schema = req.body.schema;
let connection = mysql.createConnection({
host: host,
user: user,
password: password,
database: schema,
port: 3306,
});
if (connection.state === "disconnected") {
connection.connect();
}
let selectStatement= `SELECT * FROM mydb.schema WHERE status = ${status};`;
connection.query(selectStatement, (err, results) => {
if (err) { throw err }
console.log(err);
} else {
res.json({ results });
}
});
});
Проблема:
- Я только что получил счет за облачный SQL GCP стоимостью 200 долларов за 3 недели минимального тестирования
- Соединения открываются и закрываются каждый раз при попадании в конечную точку (что может быть сотни раз на пользователя в час
- Это работало в небольших масштабах и с VPS, но это не является устойчивым с GCP Cloud SQL
Новый подход:
Реализуйте объединение, чтобы не было таких абсурдных накладных расходов, связанных с постоянным подключением.
//* CREATE CONNECTION
let getConnection = (host, user, password, database) => {
let pool = mysql.createPool({
connectionLimit:10,
host: host,
user: user,
password: password,
database: database
})
return pool
}
// Testing the initial connection
app.get('/test/:host/:user/:password/:database', (req, res) => {
let pool = getConnection(req.params.host, req.params.user, req.params.password, req.params.database)
pool.getConnection((err, db) => {
if (err) { throw err }
else {
db.query('SELECT * FROM mydb.schema LIMIT 10;', (queryErr, records) => {
if (queryErr) { throw queryErr }
else {
res.send(records)
}
db.release() //? do I release it if I know it will continue to be used?
})
}
})
})
// This endpoint will be hit hundreds of times per session. Trying to see if the original connection will carry over without having to reconnect with the config data again
//? Would I need a try catch block here?
app.get('/test2/:host/:user/:password/:database', (req, res) => {
let pool = getConnection(req.params.host, req.params.user, req.params.password, req.params.database)
pool.getConnection((err, db) => {
if (err) { throw err }
else {
db.query('SELECT * FROM mydb.schema LIMIT 10;', (queryErr, records) => {
if (queryErr) { throw queryErr }
else {
res.send(records)
}
db.release() //? do I release it if I know it will continue to be used?
})
}
})
})
- Есть ли риск, что пользователь A получит данные из базы данных пользователя B, если я полагаюсь на объединение?
- Как пул распознает запрашиваемое соединение?
- Если в настоящее время нет открытого пула, будет ли он по умолчанию создан? Нужно ли мне создавать блок try / catch, чтобы убедиться, что это произойдет?
- Правильный ли этот синтаксис?
- Если конечная точка ‘test2’ попадает в сотни раз, является ли это разумным способом справиться с этим?
Ответ №1:
Пул соединений — это кэш подключений к базе данных, которые являются общими и используются повторно для повышения задержки соединения и производительности. Когда вашему приложению требуется подключение к базе данных, оно временно заимствует его из своего пула. Когда ваше приложение завершит подключение, оно вернет соединение обратно в пул, где оно может быть повторно использовано в следующий раз, когда вашему приложению потребуется подключение к базе данных. Я бы рекомендовал вам взглянуть на эту документацию для получения более подробной информации.
Cloud SQL автоматически не обеспечивает и не настраивает балансировку нагрузки для вашего экземпляра базы данных. Вам нужно будет настроить пул соединений для распределения запросов на чтение / запись для баз данных между несколькими точками подключения.
Если вы хотите отправить несколько запросов к конечной точке, рекомендуется реализовать стратегию экспоненциального отката, поскольку это предотвращает отправку вашим приложением большого количества запросов на подключение, когда оно не может подключиться к вашей базе данных. Однако, в вашем случае, для node.js модуль mysql автоматически использует экспоненциальные задержки между неудачными попытками подключения.
Что касается риска доступа к данным от разных пользователей вашей базы данных. Я бы посоветовал вам взглянуть на эту документацию, поскольку она описывает, как Cloud SQL работает с пользователями MySQL.