使用sequelize orm向数据库发出请求时,serverless函数(serverless框架)出现问题

发布于 2025-01-19 08:07:25 字数 3870 浏览 3 评论 0 原文

我正在尝试使用无服务器框架设置一个简单的无服务器环境,只有一个lambda函数可以使用ORM续集来调用数据库。后来它将增长。

我可以使用无服务器官能线运行整个流,它可以完美地运行,包括使用semelize与数据库进行通信。但是,当我部署到AWS并运行该函数的终点时,我会在Postman和CloudWatch中获得502错误,我不会遇到任何错误,只有该函数执行的信息。

我相信问题与在server.ts文件以及pg和pg-hstore依赖关系中配置的Esbuild插件有关。

我将共享无server.ts文件,负责该功能的文件,数据库连接文件和模型。

serverless.ts

import type { AWS } from '@serverless/typescript'

const serverlessConfiguration: AWS = {
  service: 'sls-certificate',
  variablesResolutionMode: '20210326',
  frameworkVersion: '3',
  plugins: ['serverless-esbuild', 'serverless-offline'],
  provider: {
    name: 'aws',
    runtime: 'nodejs14.x',
    region: 'us-east-1',
    stage: "${opt:stage, 'dev'}",
    apiGateway: {
      minimumCompressionSize: 1024,
      shouldStartNameWithService: true,
    },
    environment: {
      AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
      NODE_OPTIONS: '--enable-source-maps --stack-trace-limit=1000',
    },
    iamRoleStatements: [
      {
        Effect: 'Allow',
        Action: ['s3:*'],
        Resource: ['*'],
      },
    ],
  },
  package: { individually: false, include: ['./src/template/**'] },
  functions: {
    generateCertificates: {
      handler: 'src/functions/generateCertificate.handler',
      events: [
        {
          http: {
            path: 'generateCertificate',
            method: 'POST',
            cors: true,
          },
        },
      ],
      environment: {
        site_api: '${param:site_api}',
        DB_NAME: '${param:DB_NAME}',
        DB_HOST: '${param:DB_HOST}',
        DB_USER: '${param:DB_USER}',
        DB_PASS: '${param:DB_PASS}',
        DB_PORT: '${param:DB_PORT}',
        stage: '${opt:stage}',
      },
    },
  },
  custom: {
    esbuild: {
      bundle: true,
      minify: false,
      sourcemap: true,
      exclude: ['aws-sdk'],
      target: 'node14',
      define: { 'require.resolve': undefined },
      platform: 'node',
      concurrency: 10,
      external: ['chrome-aws-lambda', 'pg', 'pg-hstore'],
    },
  },
}

module.exports = serverlessConfiguration

函数

import { APIGatewayProxyHandler } from 'aws-lambda'

import { RegionModel } from '../db/models/RegionModel'

export const handler: APIGatewayProxyHandler = async (
  event,
  context,
  callback,
) => {
  console.log('Init Function')

  try {
    const regions = await RegionModel.findAll({
      attributes: ['id', 'region'],
    })

    console.log('regions', regions)

    return callback(null, {
      statusCode: 201,
      body: JSON.stringify({
        regions: regions,
      }),
    })
  } catch (err) {
    return err
  }
}

续集 - 连接配置:

import { Dialect, Sequelize } from 'sequelize'

const dbName = process.env.DB_NAME as string
const dbUser = process.env.DB_USER as string
const dbHost = process.env.DB_HOST
const dbDriver = 'postgres' as Dialect
const dbPassword = process.env.DB_PASS

const sequelizeConnection = new Sequelize(dbName, dbUser, dbPassword, {
  host: dbHost,
  dialect: dbDriver,
  port: Number(process.env.DB_PORT),
})

export default sequelizeConnection

型号

import Sequelize from 'sequelize'
import sequelizeConnection from '../config'

export const RegionModel = sequelizeConnection.define('regions', {
  id: {
    type: Sequelize.INTEGER,
    allowNull: false,
    autoIncrement: true,
    primaryKey: true,
  },
  region: {
    type: Sequelize.STRING,
    allowNull: false,
  },
  created_at: {
    type: Sequelize.DATE,
    allowNull: false,
  },
  updated_at: {
    type: Sequelize.DATE,
    allowNull: false,
  },
})

edit

cloudWatch上的超时:

持续时间:50057.30毫秒邮件计费持续时间:50000 ms内存大小:1024 MB最大内存使用:229 MB INIT持续时间:1168.24 ms

I’m trying to set up a simple serverless environment using serverless framework, there is only one lambda function that makes a call to the database using ORM sequelize. Later it will grow.

I can run the entire flow using serverless-offline, it works perfectly, including communication with the database using sequelize. However, when I deploy to AWS and run the function’s endpoint, I get a 502 error in postman and cloudwatch, I don’t get any errors, only information that the function was executed.

I believe the problem is related to the esbuild plugin that is configured in the serverless.ts file and the pg and pg-hstore dependencies.

I will share the serverless.ts files, the file responsible for the function, the database connection file and the model.

serverless.ts:

import type { AWS } from '@serverless/typescript'

const serverlessConfiguration: AWS = {
  service: 'sls-certificate',
  variablesResolutionMode: '20210326',
  frameworkVersion: '3',
  plugins: ['serverless-esbuild', 'serverless-offline'],
  provider: {
    name: 'aws',
    runtime: 'nodejs14.x',
    region: 'us-east-1',
    stage: "${opt:stage, 'dev'}",
    apiGateway: {
      minimumCompressionSize: 1024,
      shouldStartNameWithService: true,
    },
    environment: {
      AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
      NODE_OPTIONS: '--enable-source-maps --stack-trace-limit=1000',
    },
    iamRoleStatements: [
      {
        Effect: 'Allow',
        Action: ['s3:*'],
        Resource: ['*'],
      },
    ],
  },
  package: { individually: false, include: ['./src/template/**'] },
  functions: {
    generateCertificates: {
      handler: 'src/functions/generateCertificate.handler',
      events: [
        {
          http: {
            path: 'generateCertificate',
            method: 'POST',
            cors: true,
          },
        },
      ],
      environment: {
        site_api: '${param:site_api}',
        DB_NAME: '${param:DB_NAME}',
        DB_HOST: '${param:DB_HOST}',
        DB_USER: '${param:DB_USER}',
        DB_PASS: '${param:DB_PASS}',
        DB_PORT: '${param:DB_PORT}',
        stage: '${opt:stage}',
      },
    },
  },
  custom: {
    esbuild: {
      bundle: true,
      minify: false,
      sourcemap: true,
      exclude: ['aws-sdk'],
      target: 'node14',
      define: { 'require.resolve': undefined },
      platform: 'node',
      concurrency: 10,
      external: ['chrome-aws-lambda', 'pg', 'pg-hstore'],
    },
  },
}

module.exports = serverlessConfiguration

function

import { APIGatewayProxyHandler } from 'aws-lambda'

import { RegionModel } from '../db/models/RegionModel'

export const handler: APIGatewayProxyHandler = async (
  event,
  context,
  callback,
) => {
  console.log('Init Function')

  try {
    const regions = await RegionModel.findAll({
      attributes: ['id', 'region'],
    })

    console.log('regions', regions)

    return callback(null, {
      statusCode: 201,
      body: JSON.stringify({
        regions: regions,
      }),
    })
  } catch (err) {
    return err
  }
}

Sequelize - connection config:

import { Dialect, Sequelize } from 'sequelize'

const dbName = process.env.DB_NAME as string
const dbUser = process.env.DB_USER as string
const dbHost = process.env.DB_HOST
const dbDriver = 'postgres' as Dialect
const dbPassword = process.env.DB_PASS

const sequelizeConnection = new Sequelize(dbName, dbUser, dbPassword, {
  host: dbHost,
  dialect: dbDriver,
  port: Number(process.env.DB_PORT),
})

export default sequelizeConnection

Model:

import Sequelize from 'sequelize'
import sequelizeConnection from '../config'

export const RegionModel = sequelizeConnection.define('regions', {
  id: {
    type: Sequelize.INTEGER,
    allowNull: false,
    autoIncrement: true,
    primaryKey: true,
  },
  region: {
    type: Sequelize.STRING,
    allowNull: false,
  },
  created_at: {
    type: Sequelize.DATE,
    allowNull: false,
  },
  updated_at: {
    type: Sequelize.DATE,
    allowNull: false,
  },
})

EDIT

TIMEOUT ON CLOUDWATCH:

Duration: 50057.30 ms Billed Duration: 50000 ms Memory Size: 1024 MB Max Memory Used: 229 MB Init Duration: 1168.24 ms

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

女中豪杰 2025-01-26 08:07:25

通常,默认配置以某种方式设置,您只能从VPC或子网内的IP访问数据库。
Lambda功能没有在专用基础架构上运行,因此具有其他一些随机IP。

在Google Cloud中,存在VPC连接器的一个概念,可以将流量从功能路由到您的VPC到数据库。我想AWS中有类似的东西。

often the default configuration is set up in a way, that you can access the database only from a ip inside the VPC or subnet.
Lambda functions are not running on dedicated infrastructure and have therefore some other random ip.

In google cloud a concept of vpc-connector exists to route the traffic from functions into your VPC to the database. I guess there is something similar in AWS.

〆一缕阳光ご 2025-01-26 08:07:25

当我将 Node 更新到高于 12 的版本时,我遇到了同样的问题。

通过将 dialectModule 添加到 Sequelize 选项,我解决了这个问题:

import * as pg from 'pg'
import Sequelize from 'sequelize'

export default new Sequelize(process.env.PG_URL, {
  dialectModule: pg,
  ...
}

我的依赖项:

{
 "pg": "^8.7.3",
 "sequelize": "^6.21.3"
}

I had the same problem when I updated my Node to a version higher than 12.

It's solved for me by adding the dialectModule to the Sequelize options:

import * as pg from 'pg'
import Sequelize from 'sequelize'

export default new Sequelize(process.env.PG_URL, {
  dialectModule: pg,
  ...
}

My dependencies:

{
 "pg": "^8.7.3",
 "sequelize": "^6.21.3"
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文