【问题标题】:"Task timed out after..." when connecting to a MongoDB database in an AWS Lambda function在 AWS Lambda 函数中连接到 MongoDB 数据库时出现“任务超时...”
【发布时间】:2021-04-27 14:00:43
【问题描述】:

我有 Node.js 脚本,在它的开头我连接到我的 MongoDB 数据库并获取特定的集合并在脚本中使用它。我在 AWS Lambda 函数中设置了这个脚本,超时时间为 10 秒。当我使用已配置的测试事件测试 AWS Lambda 时,我收到“任务在 10.00 秒后超时”。我的脚本仍然应该在它连接并完成脚本的其余部分后运行。但是,它停止了,我从 AWS Lambda 收到超时错误。如果我将超时设置得更高,例如 15 分钟,我会在脚本中连接到 MongoDB 数据库后 15 分钟收到超时错误(我在查看 AWS Lambda 函数的 CloudWatch 日志时得到了这个)。我尝试了不同的超时时间,发现在我设置超时 x 秒后,我的脚本会在我连接到 MongoDB 数据库后 x 秒给出超时错误。我遵循article 中提到的关于从 AWS Lambda 连接到 MongoDB 的所有最佳实践,它们是:在处理程序函数之外定义 MongoDB 客户端连接并将上下文属性 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 && 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
}

其他信息:我使用无服务器将脚本推送到 AWS Lambda,并使用无服务器插件“serverless-webpack”处理 TypeScript 文件。

【问题讨论】:

  • 你的 lambda 在 VPC 中吗?
  • @Marcin 不,它不在 VPC 中。
  • 致电callback 或删除它。
  • @hoangdv 我删除了回调参数,同样的事情发生了。我不知道如何调用callback,即我将在哪里调用代码以及我必须传递给它什么?
  • @hoangdv 我的处理函数也是async,所以我想我不需要callback

标签: mongodb amazon-web-services aws-lambda


【解决方案1】:

我发现 AWS Lambda 函数最多只能运行 15 分钟(即使在这段时间之后代码仍在运行)。如果我想运行脚本超过 15 分钟,我想我必须使用 AWS EC2 实例。

来源:https://aws.amazon.com/lambda/faqs/

【讨论】:

    【解决方案2】:

    您文章中链接的最佳做法是Define the MongoDB client connection outside of your handler function。在您的情况下,您应该将 const db = ... 更改为 db = ... 并在处理程序函数之外声明 db 并将其更改为 let db = null,就像文章中的示例一样,这样您就可以在不同的 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 发出信号,表明您已完成处理事件。这应该可以解决问题。

    【讨论】:

    • 我试过这个,我直接在 handler 函数之外定义了 db 变量,但我得到了同样的超时错误。在我连接到数据库后,我还通过调用callback() 进行了尝试,但是,代码只是在回调处停止,并带有null 响应。
    猜你喜欢
    • 1970-01-01
    • 2021-10-17
    • 2020-09-02
    • 2018-07-23
    • 2017-12-09
    • 1970-01-01
    • 2017-10-05
    • 2017-09-20
    • 2019-11-06
    相关资源
    最近更新 更多