【问题标题】:Saving data to Postgres from AWS Lambda从 AWS Lambda 将数据保存到 Postgres
【发布时间】:2019-01-11 13:58:39
【问题描述】:

我正在构建一个 lambda 函数,它应该将游戏反馈(例如性能等级)保存到我的 Postgres 数据库中,该数据库位于 AWS RDS 中。

我正在使用 NodeJS 打字稿,该功能有点工作,但方式很奇怪。

我创建了一个 API 网关,因此我可以将数据发布到 lambda 处理它的 URL 并保存,问题是,当我发布数据时,该函数似乎会处理它,直到它达到连接客户端的最大限制,而且它似乎丢失了其他客户的数据。

另一个问题是,每次我发布数据时,我都会收到一个响应,说存在内部服务器错误并且带有“X-Cache→Error from cloudfront”标头。对于 GET 请求,我发现它给了我这个响应,因为响应的格式不正确,但在这种情况下,我修复了响应格式,但仍然遇到这个问题......

有时我会收到超时响应。

我的函数代码:

import { APIGatewayEvent, Callback, Context, Handler } from "aws-lambda";
import { QueryConfig, Client, Pool, PoolConfig } from "pg";

export const insert: Handler = async (
  event: APIGatewayEvent,
  context: Context,
  cb: Callback
) => {
  // context.callbackWaitsForEmptyEventLoop = false;

  const config: PoolConfig = {
    user: process.env.PG_USER,
    host: process.env.PG_HOST,
    database: process.env.PG_DB,
    password: process.env.PG_PASS,
    port: parseInt(process.env.PG_PORT),
    idleTimeoutMillis: 0,
    max: 10000
  };

  const pool = new Pool(config);

  let postdata = event.body || event;

  console.log("POST DATA:", postdata);

  if (typeof postdata == "string") {
    postdata = JSON.parse(postdata);
  }

  let query: QueryConfig = <QueryConfig>{
    name: "get_all_questions",
    text:
      "INSERT INTO gamefeedback (gameid, userid, presenterstars, gamestars) VALUES ($1, $2, $3, $4);",
    values: [
      parseInt(postdata["game_id"]),
      postdata["user_id"],
      parseInt(postdata["presenter_stars"]),
      parseInt(postdata["game_stars"])
    ]
  };
  console.log("Before Connect");

  let con = await pool.connect();

  let res = await con.query(query);

  console.log("res.rowCount:", res.rowCount);

  if (res.rowCount != 1) {
    cb(new Error("Error saving the feedback."), {
      statusCode: 400,
      body: JSON.stringify({
        message: "Error saving data!"
      })
    });
  }

  cb(null, {
    statusCode: 200,
    body: JSON.stringify({
      message: "Saved successfully!"
    })
  });
  console.log("The End");
};

CloudWatch 错误日志中连接的最大客户端数如下所示:

2018-08-03T15:56:04.326Z    b6307573-9735-11e8-a541-950f760c0aa5    (node:1) UnhandledPromiseRejectionWarning: error: sorry, too many clients already
at u.parseE (/var/task/webpack:/node_modules/pg/lib/connection.js:553:1)
at u.parseMessage (/var/task/webpack:/node_modules/pg/lib/connection.js:378:1)
at Socket.<anonymous> (/var/task/webpack:/node_modules/pg/lib/connection.js:119:1)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at Socket.Readable.push (_stream_readable.js:208:10)
at TCP.onread (net.js:607:20)

谁能帮我解决这个奇怪的问题?

谢谢

【问题讨论】:

    标签: node.js postgresql amazon-web-services typescript aws-lambda


    【解决方案1】:

    首先,您需要在处理程序之上创建一个池,如下所示:

    const config: PoolConfig = {
      user: process.env.PG_USER,
      ...
    };
    
    const pool = new Pool(config);
    
    export const insert: Handler = async (
      event: APIGatewayEvent,
      context: Context,
      cb: Callback
    ) => {
    
    ..etc
    

    您拥有它的方式是在每次调用时创建一个池。如果您在处理程序之外创建池,它使 Lambda 有机会在调用之间共享池。

    【讨论】:

      猜你喜欢
      • 2021-02-06
      • 2021-02-02
      • 2018-06-08
      • 1970-01-01
      • 2021-04-16
      • 2019-05-27
      • 2021-02-04
      • 1970-01-01
      • 2016-09-22
      相关资源
      最近更新 更多