Lambda + pg-promise + transaction = 随机超时。

问题描述 投票:0回答:1

在过去的48小时里,我一直在为这个问题而苦恼,在阅读了这里的很多答案、博客、文章、文档等之后......。我仍然找不到解决方案

基本上,我有一个2分钟超时的lambda函数。根据日志和洞察力,它处理大部分请求都很好,但当试图执行下面的事务时,它随机失败,出现 "超时 "错误。

Lambda代码(为了便于阅读而砍掉)。


import pgp from 'pg-promise'
import logger from '../lib/logger'

const Database = pgp()

const db = Database({
 connectionString: process.env.DATABASE_URL,
 max: 3,
 idleTimeoutMillis: 10000,
})

db.connect()
 .then(() => logger.info('Successfully connected to the PG database'))
 .catch(err => logger.error({ err }))

export const handler = async (event, context) => {
 logger.info('transaction start...')

 await db.tx(async tx => {
   await tx.none(
     `
     INSERT INTO...`,
     [someValue1, someValue2]
   )
   const updatedRow = await tx.one(
     `
     UPDATE Something...`,
     [somethingId]
   )
   return someFunction(updatedRow)
 })

 logger.info('transaction end...')
}

const someFunction = async (data) => {
 return db.task('someTask', async ctx => {
   const value = await ctx.oneOrNone(
     `SELECT * FROM Something...`,
     [data.id]
   )

   if (!value) {
     return
   }

   const doStuff = async (points) =>
     ctx.none(
       `UPDATE Something WHERE id =.....`,
       [points]
     )

   // increment points x miles
   if (data.condition1) {
     await doStuff(10)
   }

   if (data.condition2) {
     await doStuff(20)
   }

   if (data.condition3) {
     await doStuff(30)
   }
 })
}

我看到事务开始了,但从未结束,所以函数不可避免地被超时杀死。

我阅读了整个wiki中的 承诺 并了解了关于调整、性能、好的做法等一切。但还是有很大的问题。

你可以看到,我也改变了实验用的池大小和最大超时,但它没有解决这个问题。

有什么想法吗?

谢谢!我一直在纠结这个问题。

node.js lambda timeout pg-promise
1个回答
0
投票

最有可能的是你的连接数用完了。你没有正确使用它们,同时你设置了一个很低的3个连接限制。

第一个问题,你在测试连接时,通过调用 connect,而不随之而来的是 done这将永久地占用,从而浪费你的初始主连接。例子 我们在测试后释放了连接。

第二个问题 - 你正在请求一个新的连接(通过调用 .task 根上 db 级),这对任何环境都是不好的,而当你的连接很少时,这一点尤其关键。

任务应该是重复使用当前事务的连接,这意味着你的 someFunction 应该要求连接上下文,或者至少将其作为可选参数。

const someFunction = async (data, ctx) => {
 return (ctx || db).task('someTask', async tx => {
   const value = await tx.oneOrNone(

Task <-> Task <-> Task <-> Task <-> Task <-> Task <-> Task <-> Task <-> Task <-> Task <-> Task <-> Task <-> Task <-> Transaction interfaces in pg-promise 可以完全互嵌,你看,把当前的连接传播到各个层次。

另外,我建议使用 pg-monitor,实现良好的查询+上下文可视化。

© www.soinside.com 2019 - 2024. All rights reserved.