【问题标题】:Problem in serverless function (serverless framework) when using sequelize orm to make requests to the database使用 sequelize orm 向数据库发出请求时,无服务器功能(无服务器框架)出现问题
【发布时间】:2022-07-15 21:27:49
【问题描述】:

我正在尝试使用无服务器框架设置一个简单的无服务器环境,只有一个 lambda 函数使用 ORM sequelize 调用数据库。以后会长大的。

我可以使用 serverless-offline 运行整个流程,它运行良好,包括使用 sequelize 与数据库通信。但是,当我部署到 AWS 并运行函数的端点时,我在 postman 和 cloudwatch 中收到 502 错误,我没有收到任何错误,只有函数已执行的信息。

我认为问题与 serverless.ts 文件中配置的 esbuild 插件以及 pg 和 pg-hstore 依赖项有关。

我会分享serverless.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
  }
}

Sequelize - 连接配置:

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,
  },
})

编辑

CLOUDWATCH 超时:

持续时间:50057.30 毫秒计费持续时间:50000 毫秒内存大小:1024 MB 使用的最大内存:229 MB 初始化持续时间:1168.24 毫秒

【问题讨论】:

  • 打印出 catch 块中的错误 - console.log(err)
  • 它没有陷入困境。我增加了函数的超时时间,并意识到它在搜索时崩溃了。请参阅我在问题末尾添加的 cloudwatch 日志。

标签: typescript postgresql sequelize.js serverless-framework esbuild


【解决方案1】:

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

在谷歌云中,存在一个 vpc 连接器的概念,用于将流量从函数路由到您的 VPC 到数据库。我猜 AWS 中也有类似的东西。

【讨论】:

    【解决方案2】:

    当我将 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"
    }
    

    【讨论】:

      猜你喜欢
      • 2015-09-21
      • 1970-01-01
      • 2016-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多