使用无服务器框架(AWS Lambda/网关)、Express、Mongoose/MongoDB Atlas 的应用程序频繁超时

Abk*_*Abk 8 mongoose express aws-lambda aws-api-gateway serverless-framework

触发警告:初学者问题。

\n\n

我使用 Express 和 Mongoose 以及 MongoDB Atlas DB 构建了一个 api。

\n\n

大多数时候,它工作正常,但经常出现超时错误。这似乎是非常随机发生的,涉及所有路线等......准确地说,我得到:

\n\n
`502 Internal server error via POSTMAN`\n
Run Code Online (Sandbox Code Playgroud)\n\n

在无服务器仪表板中,我得到:

\n\n
invocation\ntime invoked 1 day ago, mar 08 at 1:38pm\nfatal error Function execution duration going to exceeded configured timeout limit.\ncold start\nduration 48.9 s\nmemory used na\n\nrequest\nendpoint /{proxy+}\nmethod POST\nstatus 502\nmessage Internal server error\nlatency 27 ms\n
Run Code Online (Sandbox Code Playgroud)\n\n

和跨度和日志:

\n\n

跨越并登录无服务器仪表板

\n\n

我使用本教程来包装我的 Express 应用程序,以使用无服务器框架进行部署:https://dev.to/adnanrahic/a-crash-course-on-serverless-apis-with-express-and-mongodb-193k

\n\n

无服务器.yml 文件:

\n\n
service: serviceName\napp: appName\norg: orgName\n\nprovider:\n  name: aws\n  runtime: nodejs12.x\n  stage: ${env:NODE_ENV}\n  region: eu-central-1\n  environment:\n    NODE_ENV: ${env:NODE_ENV}\n    DB: ${env:DB}\n\nfunctions:\n  app:\n    handler: server.run\n    events:\n      - http:\n          path: /\n          method: ANY\n          cors: true\n      - http:\n          path: /{proxy+}\n          method: ANY\n          cors: true\n\nplugins:\n  - serverless-offline # Utiliser pour tester localement\n  - serverless-dotenv-plugin\n
Run Code Online (Sandbox Code Playgroud)\n\n

server.js 文件:

\n\n
const sls = require(\'serverless-http\')\nconst app = require(\'./app\')\nmodule.exports.run = sls(app)\n
Run Code Online (Sandbox Code Playgroud)\n\n

app.js 文件:

\n\n
const express = require(\'express\')\nconst cors = require(\'cors\')\nconst bodyParser = require(\'body-parser\')\n\nconst newRoutes = require(\'./routes/file\')\n\nconst app = express()\n\napp.use(bodyParser.json())\nconst helmet = require(\'helmet\')\napp.use(helmet())\n\napp.options(\'*\', cors())\napp.use(cors({ allowedHeaders: \'Content-Type, Authorization\' }))\n\napp.use(\'/new-route\', newRoutes)\n\napp.use((error, req, res, next) => {\n  console.log(error)\n  const status = error.status || 500\n  const message = error.message\n  res.status(status).json({\n    status: status,\n    message: message\n  })\n})\n\n// G\xc3\xa8re la connexion \xc3\xa0 la base de donn\xc3\xa9e :\nrequire(\'./db\')\n\nmodule.exports = app\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后是 db.js 文件:

\n\n
const mongoose = require(\'mongoose\')\n\nmongoose\n  .connect(\n    process.env.DB, {\n      useNewUrlParser: true,\n      useUnifiedTopology: true\n    })\n  .then(() => {\n    console.log(\'connected\')\n  })\n  .catch(err => console.log(err))\n
Run Code Online (Sandbox Code Playgroud)\n\n

据我了解,这与 Lambda 中的冷启动以及 API Gateway 处理超时的方式有关(!?)。我已经在猫鼬文档(https://mongoosejs.com/docs/lambda.html)上阅读了这篇文章,还阅读了其他教程,但我不知道应该如何精确地使其适应我的情况。

\n\n

感谢您的帮助

\n

Asf*_*had 8

在您的提供程序下添加超时,lambda 中的超时最大值为 900 秒,根据您的执行时间(如 30 秒)放置它,看看会发生什么

provider:
  timeout: 30
Run Code Online (Sandbox Code Playgroud)

该错误清楚地表明它的执行超出了超时时间,因为您尚未配置超时,所以它使用默认的 3 秒超时,希望它能解决问题


Ale*_*lex 3

该问题可能是由于您打开的数据库连接造成的。当建立此连接时,任何调用callback不会返回给客户端,并且您的函数将超时。

\n\n

您需要设置context.callbackWaitsForEmptyEventLoopfalse.

\n\n

这是文档的解释

\n\n
\n

callbackWaitsForEmptyEventLoop \xe2\x80\x93 设置为 false 可在回调执行时立即发送响应,而不是等待 Node.js 事件循环为空。如果这是 false,则任何未完成的事件将在下一次调用期间继续运行。

\n
\n\n

您可以在您的计算机中轻松serverless-http设置此选项server.js

\n\n
const sls = require(\'serverless-http\')\nconst app = require(\'./app\')\n\nmodule.exports.run = sls(app, { callbackWaitsForEmptyEventLoop: false })\n
Run Code Online (Sandbox Code Playgroud)\n