Проблема
Я использую mssql
v6.2.0 в Lambda, которая часто вызывается (постоянно ~ 25 одновременных вызовов при стандартной нагрузке).
Кажется, у меня проблемы с пулом соединений или чем-то в этом роде, потому что у меня по-прежнему тонны открытых соединений с БД, которые перегружают мою базу данных (SQL Сервер на RDS), в результате чего лямбды просто теряют время ожидания результатов запроса.
Я прочитал документы, различные похожие вопросы, проблемы с Github и т. д. c. но ничего не помогло с этой конкретной проблемой. разделяется между вызовами в одном контейнере. Это заставляет меня думать, что я должен видеть всего несколько соединений для каждого контейнера, в котором работает моя Lambda, но я не знаю, сколько их, поэтому это трудно проверить. Суть в том, что пул должен удерживать меня от тонны и тонны открытых соединений, поэтому что-то работает неправильно.
Есть несколько разных способов использования
mssql
, и я пробовал несколько из них. Примечательно, что я пытался указать максимальный размер пула как с большими, так и с маленькими значениями, но получил те же результаты. AWS рекомендует вам проверить, существует ли уже пул, прежде чем пытаться создать новый. Я пробовал это безрезультатно. Это было что-то вроде
pool = pool || await createPool()
Я знаю, что прокси-сервер RDS существует для помощи в подобных ситуациях, но, похоже, он не предлагается (в настоящее время) для SQL экземпляров сервера. У меня есть возможность немного замедлить мои данные, но это немного влияет на производительность продукта в целом, поэтому я не хочу делать это только для того, чтобы избежать решения проблемы с подключениями к БД. Если флажок не установлен, я увидел до 700 подключений к БД одновременно, что заставило меня подумать, что есть какая-то утечка, и это, возможно, не просто разумный результат большого использования. I не нашел способа сократить TTL для подключений на стороне сервера SQL, как рекомендовано этим слайдом re: Invent. Возможно, это часть ответа?
Code
'use strict';
/* Dependencies */
const sql = require('mssql');
const fs = require('fs').promises;
const path = require('path');
const AWS = require('aws-sdk');
const GeoJSON = require('geojson');
AWS.config.update({ region: 'us-east-1' });
var iotdata = new AWS.IotData({ endpoint: process.env['IotEndpoint'] });
/* Export */
exports.handler = async function (event) {
let myVal= event.Records[0].Sns.Message;
// Gather prerequisites in parallel
let [
query1,
query2,
pool
] = await Promise.all([
fs.readFile(path.join(__dirname, 'query1.sql'), 'utf8'),
fs.readFile(path.join(__dirname, 'query2.sql'), 'utf8'),
sql.connect(process.env['connectionString'])
]);
// Query DB for updated data
let results = await pool.request()
.input('MyCol', sql.TYPES.VarChar, myVal)
.query(query1);
// Prepare IoT Core message
let params = {
topic: `${process.env['MyTopic']}/${results.recordset[0].TopicName}`,
payload: convertToGeoJsonString(results.recordset),
qos: 0
};
// Publish results to MQTT topic
try {
await iotdata.publish(params).promise();
console.log(`Successfully published update for ${myVal}`);
//Query 2
await pool.request()
.input('MyCol1', sql.TYPES.Float, results.recordset[0]['Foo'])
.input('MyCol2', sql.TYPES.Float, results.recordset[0]['Bar'])
.input('MyCol3', sql.TYPES.VarChar, results.recordset[0]['Baz'])
.query(query2);
} catch (err) {
console.log(err);
}
};
/**
* Convert query results to GeoJSON for API response
* @param {Array|Object} data - The query results
*/
function convertToGeoJsonString(data) {
let result = GeoJSON.parse(data, { Point: ['Latitude', 'Longitude']});
return JSON.stringify(result);
}
Вопрос
Пожалуйста, помогите мне понять, почему у меня появляются неконтролируемые соединения и как это исправить. Для бонусных баллов: какова идеальная стратегия для обработки высокого уровня параллелизма БД на Lambda?
В конечном итоге эта служба должна обрабатывать в несколько раз больше текущей нагрузки - я понимаю, что это становится довольно большой нагрузкой. Я открыт для таких вариантов, как реплики чтения или другие меры по повышению производительности чтения, если они совместимы с SQL сервером, и они не просто средство для написания правильного кода доступа к БД.
Пожалуйста, дайте мне знать, если я смогу улучшить вопрос. Я знаю, что есть похожие, но я прочитал / попробовал много из них и не нашел их, чтобы помочь. Заранее благодарим!
Сопутствующие материалы