You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Serverless-offline运行NestJS本地后端频繁出现Lambda 504超时求助

问题

使用serverless-offline插件本地运行NestJS后端,服务有时能正常运行,但发起任意请求(GET/POST均可)后,终端频繁出现**「× [504] - Lambda timeout」**错误。完整错误信息如下:

{"errorMessage":"[504] - Lambda timeout.","errorType":"LambdaTimeoutError","stackTrace":["Error: [504] - Lambda timeout.","at #timeoutAndTerminate (file:///C:/Users/z0044vnt/Desktop/diplomka/application-compliance-suite-monorepo/node_modules/serverless-offline/src/lambda/LambdaFunction.js:283:11)","at async LambdaFunction.runHandler (file:///C:/Users/z0044vnt/Desktop/diplomka/application-compliance-suite-monorepo/node_modules/serverless-offline/src/lambda/LambdaFunction.js:305:16)","at async file:///C:/Users/z0044vnt/Desktop/diplomka/application-compliance-suite-monorepo/node_modules/serverless-offline/src/events/http/HttpServer.js:602:18)","at async exports.Manager.execute (C:\Users\z0044vnt\Desktop\diplomka\application-compliance-suite-monorepo\node_modules\@hapi\hapi\lib\toolkit.js:60:28)","at async internals.handler (C:\Users\z0044vnt\Desktop\diplomka\application-compliance-suite-monorepo\node_modules\@hapi\hapi\lib\handler.js:46:20)","at async exports.execute (C:\Users\z0044vnt\Desktop\diplomka\application-compliance-suite-monorepo\node_modules\@hapi\hapi\lib\handler.js:31:20)","at async Request._lifecycle (C:\Users\z0044vnt\Desktop\diplomka\application-compliance-suite-monorepo\node_modules\@hapi\hapi\lib\request.js:370:32)"]}

此时NestJS应用甚至无法启动,Lambda已设置29秒超时,但实际远早于该时间就触发超时。本地服务器启动后所有请求均超时,执行命令sls offline --stage local --ignoreJWTSignature --noAuth后的终端输出:

npm run be:local

> application-compliance-suite-monorepo@0.0.0 be:local
> nx run backend:serve:local


> nx run backend:serve:local

Starting Offline at stage local (eu-central-1)
No errors found.
Offline [http for lambda] listening on http://localhost:3002
Function names exposed for local invocation by aws-sdk:
           * main: application-compliance-suite-backend-local-main

 │                                                                           │
 │   ANY     | http://localhost:3000/{proxy*}                                │
 │   POST    | http://localhost:3000/2015-03-31/functions/main/invocations   │
 │   GET     | http://localhost:3000/swagger                                 │
 │   POST    | http://localhost:3000/2015-03-31/functions/main/invocations   │
 │   GET     | http://localhost:3000/swagger/{proxy*}                        │
 │   POST    | http://localhost:3000/2015-03-31/functions/main/invocations   │
 │   OPTIONS | http://localhost:3000/{proxy*}                                │
 │   POST    | http://localhost:3000/2015-03-31/functions/main/invocations   │
 │   GET     | http://localhost:3000/local/swagger                           │
 │   POST    | http://localhost:3000/2015-03-31/functions/main/invocations   │
 │   GET     | http://localhost:3000/local/swagger/{proxy*}                  │
 │   POST    | http://localhost:3000/2015-03-31/functions/main/invocations   │
 │                                                                           │
 └───────────────────────────────────────────────────────────────────────────┘

Server ready: http://localhost:3000 🚀
GET /local/swagger (λ: main)
× [504] - Lambda timeout.
ANY /favicon.ico (λ: main)
× [504] - Lambda timeout.

serverless.yml中的Lambda配置

functions:
    main:
        handler: src/main.handler
        memorySize: 256
        timeout: 29
        role: !GetAtt MainLambdaFunctionIAMRole.Arn
        vpc: ${file(serverless/sls-mappings.yml):stageMap.${self:provider.stage}.vpc}
        layers:
            - !Ref DependenciesLambdaLayer
        environment:
            STAGE: ${self:provider.stage}
            NO_COLOR: true
            REGION: ${self:custom.environmentVariables.${self:provider.stage}.region}
            DB_SECRET: ${self:custom.environmentVariables.${self:provider.stage}.dbSecret}
        events:
            - httpApi: # ApiGatewayV2
                  method: any
                  path: /{proxy+}
                  authorizer:
                      name: customAuthorizer
            - httpApi: # Escape swagger
                  method: get
                  path: /swagger
            - httpApi: # Escape swagger
                  method: get
                  path: /swagger/{proxy*}
            - httpApi: # escaping the OPTIONS call
                  method: options
                  path: /{proxy+}
            - httpApi: # Escape swagger base url staged
                  method: get
                  path: /${self:provider.stage}/swagger
            - httpApi: # Escape swagger staged
                  method: get
                  path: /${self:provider.stage}/swagger/{proxy*}

package.json依赖配置

{
    "name": "application-compliance-suite-monorepo",
    "version": "0.0.0",
    "license": "MIT",
    "scripts": {
        "nx": "nx",
        "be:local": "nx run backend:serve:local",
        "fe:local": "nx run frontend:serve:local"
    },
    "private": true,
    "devDependencies": {
        "@angular-devkit/build-angular": "16.0.0",
        "@angular-eslint/eslint-plugin": "16.0.1",
        "@angular-eslint/eslint-plugin-template": "16.0.1",
        "@angular-eslint/template-parser": "16.0.1",
        "@angular/cli": "16.0.0",
        "@angular/compiler-cli": "16.0.0",
        "@angular/language-service": "16.0.0",
        "@nestjs/testing": "9.1.1",
        "@ngxs/devtools-plugin": "^3.8.1",
        "@ngxs/logger-plugin": "^3.8.1",
        "@nx/angular": "16.1.4",
        "@nx/cypress": "16.1.4",
        "@nx/esbuild": "16.1.4",
        "@nx/eslint-plugin": "16.1.4",
        "@nx/jest": "16.1.4",
        "@nx/js": "16.1.4",
        "@nx/linter": "16.1.4",
        "@nx/nest": "16.1.4",
        "@nx/node": "16.1.4",
        "@nx/workspace": "16.1.4",
        "@types/aws-lambda": "^8.10.110",
        "@types/jest": "^28.1.1",
        "@types/node": "18.7.1",
        "@types/node-rsa": "^1.1.1",
        "@types/passport-jwt": "^3.0.6",
        "@types/uuid": "^9.0.0",
        "@typescript-eslint/eslint-plugin": "5.58.0",
        "@typescript-eslint/parser": "5.58.0",
        "aws-cdk": "^2.62.0",
        "aws-cdk-lib": "^2.62.0",
        "constructs": "^10.1.231",
        "copy-webpack-plugin": "^11.0.0",
        "cypress": "^12.2.0",
        "esbuild": "0.17.17",
        "eslint": "~8.15.0",
        "eslint-config-prettier": "8.1.0",
        "eslint-plugin-cypress": "^2.10.3",
        "eslint-plugin-prettier": "^4.2.1",
        "jest": "^29.5.0",
        "jest-environment-jsdom": "^29.5.0",
        "jest-preset-angular": "13.1.0",
        "ng-packagr": "^16.0.1",
        "ngx-translate-testing": "^6.1.0",
        "nx": "16.1.4",
        "postcss": "^8.4.5",
        "postcss-import": "~14.1.0",
        "postcss-preset-env": "~7.5.0",
        "postcss-url": "~10.1.3",
        "prettier": "^2.6.2",
        "serverless": "^3.26.0",
        "serverless-offline": "^12.0.4",
        "serverless-plugin-reducer": "^4.0.1",
        "serverless-webpack": "^5.11.0",
        "ts-jest": "29.1.0",
        "ts-node": "10.9.1",
        "typescript": "5.0.4"
    },
    "dependencies": {
        "@angular/animations": "16.0.0",
        "@angular/cdk": "16.0.0",
        "@angular/common": "16.0.0",
        "@angular/compiler": "16.0.0",
        "@angular/core": "16.0.0",
        "@angular/forms": "16.0.0",
        "@angular/material": "16.0.0",
        "@angular/platform-browser": "16.0.0",
        "@angular/platform-browser-dynamic": "16.0.0",
        "@angular/router": "16.0.0",
        "@automapper/classes": "^8.7.7",
        "@automapper/core": "^8.7.7",
        "@automapper/nestjs": "^8.7.7",
        "@automapper/types": "^6.3.1",
        "@aws-sdk/client-secrets-manager": "^3.264.0",
        "@aws-sdk/client-sqs": "^3.272.0",
        "@fastify/aws-lambda": "^3.0.0",
        "@fastify/static": "^6.10.2",
        "@fastify/swagger": "^8.3.1",
        "@nestjs/common": "9.1.1",
        "@nestjs/config": "^2.3.0",
        "@nestjs/core": "9.1.1",
        "@nestjs/jwt": "^10.0.0",
        "@nestjs/passport": "^9.0.0",
        "@nestjs/platform-fastify": "^9.2.0",
        "@nestjs/schematics": "9.1.0",
        "@nestjs/swagger": "6.3.0",
        "@nestjs/typeorm": "^9.0.1",
        "@ngx-translate/core": "^14.0.0",
        "@ngx-translate/http-loader": "^7.0.0",
        "@ngxs/store": "^3.8.1",
        "angular-auth-oidc-client": "^15.0.3",
        "axios": "^1.2.3",
        "class-transformer": "^0.5.1",
        "class-validator": "^0.14.0",
        "css-vars-ponyfill": "^2.4.8",
        "node-rsa": "^1.1.1",
        "passport": "^0.6.0",
        "passport-custom": "^1.1.1",
        "pg": "^8.11.0",
        "reflect-metadata": "^0.1.13",
        "rxjs": "~7.5.0",
        "tslib": "^2.5.0",
        "typeorm": "^0.3.16",
        "zone.js": "^0.13.0"
    }
}

运行环境:Windows 10、Node 18.16.0,本地资源占用(CPU、内存等)正常。


原因分析与解决方案

1. 本地VPC配置冲突

serverless.yml中为local阶段配置了VPC,但本地环境没有对应的VPC网络,导致Lambda进程无法正常初始化,进而触发超时。

解决办法

在serverless.yml中针对local阶段移除VPC配置:

  • 修改vpc字段为条件判断,仅在非local阶段启用:
vpc: ${file(serverless/sls-mappings.yml):stageMap.${self:provider.stage}.vpc, ""}

或者直接在local环境的配置映射文件中,将vpc值设为空。

2. 依赖版本不兼容

当前使用的serverless-offline@12.0.4与serverless@3.26.0、NestJS@9.x存在兼容性问题,导致Lambda函数执行时出现阻塞。

解决办法

  • 降级serverless-offline到稳定兼容版本,比如^11.5.0:
npm uninstall serverless-offline
npm install serverless-offline@11.5.0 --save-dev
  • 或者升级serverless到最新稳定版,确保与serverless-offline版本匹配。

3. 数据库连接阻塞

local阶段的DB_SECRET指向的数据库无法访问,NestJS启动时卡在数据库连接环节,导致Lambda超时。

解决办法

  • 检查local阶段的数据库配置,确保本地能正常连接到目标数据库;
  • 若本地不需要数据库,临时注释NestJS中TypeORM模块的初始化代码,或者为local阶段配置本地测试数据库(如SQLite)。

4. NestJS启动逻辑阻塞

NestJS应用在启动时的异步操作(如配置加载、第三方服务连接)未正确处理,导致Lambda进程无法完成初始化。

解决办法

  • 在NestJS的main.ts中,确保bootstrap()函数正确处理异步操作并捕获错误:
async function bootstrap() {
  try {
    const app = await NestFactory.create(AppModule);
    // 其他配置逻辑
    await app.init();
  } catch (error) {
    console.error('NestJS启动失败:', error);
    process.exit(1);
  }
}
bootstrap();
  • 检查自定义守卫、拦截器或中间件,排查是否存在未正确处理的异步阻塞逻辑。

5. Windows系统路径/权限问题

Windows系统的文件路径格式可能与serverless-offline预期不符,或者进程没有足够权限读取文件。

解决办法

  • 确保项目路径中无中文、空格或特殊字符;
  • 以管理员身份运行终端,重新启动服务;
  • 清理依赖后重新安装:
rm -rf node_modules package-lock.json
npm install

内容的提问来源于stack exchange,提问作者hawran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:22:00