#mongodb #amazon-web-services #aws-lambda
#mongodb #amazon-web-services #aws-lambda
Вопрос:
У меня есть Node.js сценарий, в начале которого я подключаюсь к своей базе данных MongoDB, получаю определенную коллекцию и использую ее в скрипте. Я установил этот скрипт в функции AWS Lambda с таймаутом 10 секунд. Когда я тестирую AWS Lambda с помощью настроенного тестового события, я получаю сообщение «Время ожидания задачи истекло через 10.00 секунд». Предполагается, что мой скрипт по-прежнему будет запускаться после его подключения и завершения остальной части скрипта. Однако он останавливается, и я получаю сообщение об ошибке тайм-аута от AWS Lambda. Если я устанавливаю время ожидания выше, например, 15 минут, я получаю ошибку тайм-аута через 15 минут после подключения к базе данных MongoDB в скрипте (я понял это, просматривая журналы CloudWatch для функции AWS Lambda). Я экспериментировал с разными таймингами тайм-аута и обнаружил, что в течение x секунд, которые я устанавливаю для тайм-аута, мой скрипт выдает ошибку тайм-аута через x секунд после подключения к базе данных MongoDB. Я следовал всем рекомендациям, упомянутым в этой статье о подключении к MongoDB из AWS Lambda, и они следующие: определение клиентского соединения MongoDB вне функции обработчика и установка свойства context callbackWaitsForEmptyEventLoop
на false
. Я не уверен, как это исправить. Ниже приведен некоторый соответствующий код, который я использовал в своем скрипте:
main.ts
:
import { connectToDatabase } from './mongodb'
import mongodb from 'mongodb'
export const handler = async (event: any, context: any, callback: any) => {
context.callbackWaitsForEmptyEventLoop = false
const db = await connectToDatabase().then((db: mongodb.Db) => db).catch(error => error)
var collection: mongodb.Collection = db.collection("{collection-name}")
// Rest of the script
}
mongodb.ts
:
import mongodb, { MongoClient } from "mongodb"
let uri: undefined | string = process.env.MONGODB_URI
let dbName: undefined | string = process.env.MONGODB_DB
let cachedClient: null | mongodb.MongoClient = null
let cachedDb: null | mongodb.Db = null
export async function connectToDatabase() {
if (cachedClient amp;amp; cachedDb) {
return cachedDb
}
if (!uri) {
throw new Error(
"Please define the MONGODB_URI environment variable inside .env.local"
)
}
if (!dbName) {
throw new Error(
"Please define the MONGODB_DB environment variable inside .env.local"
)
}
const client = await MongoClient.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
const db = client.db(dbName)
cachedClient = client
cachedDb = db
return db
}
Другая информация: я использую serverless для отправки скрипта в AWS Lambda, а также использую бессерверный плагин «serverless-webpack» для файлов TypeScript.
Комментарии:
1. Ваш лямбда-код в VPC?
2. @Marcin Нет, это не в VPC.
3. Вызовите
callback
или удалите его.4. @hoangdv Я удалил параметр обратного вызова, и происходит то же самое. Я не знаю, как вызвать
callback
, т.е. куда я должен позвонить в коде и что я должен передать ему?5. @hoangdv Также моя функция-обработчик
async
, поэтому я думаю, что мне это не понадобитсяcallback
.
Ответ №1:
В рекомендации, приведенной в вашей статье, говорится Define the MongoDB client connection outside of your handler function
. В вашем случае вам следует изменить const db = ...
db = ...
и объявить db
вне вашей функции-обработчика и изменить ее на let db = null
like в примере в статье, чтобы вы могли повторно использовать соединения в разных вызовах Lambda. Например:
let db = null;
export const handler = async (event, context, callback) => {
if (!db) {
db = connectToDatabase();
}
// do something with your db
callback();
};
Кроме того, воспользуйтесь советом @hoangdv и вызовите callback
функцию, чтобы сообщить AWS Lambda, что вы закончили обработку события. Это должно сработать.
Комментарии:
1. Я попробовал это, где я определяю
db
переменную непосредственно внеhandler
функции, но получаю ту же ошибку тайм-аута. Я также пробовал это с помощью вызоваcallback()
после подключения к базе данных, однако код просто останавливается при обратном вызове сnull
ответом.
Ответ №2:
Я обнаружил, что функции AWS Lambda могут выполняться не более 15 минут (даже если код все еще выполняется по истечении этого промежутка времени). Если бы я хотел запускать скрипт более 15 минут, я думаю, мне пришлось бы использовать экземпляр AWS EC2.
Источник: https://aws.amazon.com/lambda/faqs /