如何处理 Vercel 无服务器函数中的 Postgres 连接池? (“角色连接太多”)

How to handle Postgres connection pooling in Vercel serverless functions? (“too many connections for role”)

我有一个基于此模板构建的小型爱好网络应用程序:https://github.com/tomsoderlund/nextjs-pwa-graphql-sql-boilerplate

它使用 ElephantSQL 的免费套餐(5 个连接),在 Zeit Now v2 无服务器函数上运行 – 并使 运行 远离 Postgres 连接(“角色“djsktctf”的连接过多运行 =33=]”).

我正在使用 death NPM 关闭连接 - 这是在 /api/graphql/index.js:

const { ApolloServer, gql } = require('apollo-server-micro')
const { config } = require('../../config/config')

// Postgres (pg)
const { Pool } = require('pg')
const onProcessDeath = require('death')
const pool = new Pool({ connectionString: config.databaseUrl })
let client

const initDatabaseClient = async () => {
  if (!client) client = await pool.connect()
}
initDatabaseClient()

onProcessDeath((signal, err) => {
  client && client.release()
})

const typeDefs = gql`
  ${require('../../graphql/font/schema')}
`

const resolvers = {
  ...require('../../graphql/font/resolvers')(pool)
}

const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: true,
  playground: true
})

module.exports = server.createHandler({ path: config.graphqlPath })

然后在 resolvers 里面看起来像这样:

module.exports = (pool) => ({
  Query: {
    async articles (parent, variables, context, info) {
      const sqlString = `SELECT * FROM article LIMIT 100;`
      const { rows } = await pool.query(sqlString)
      return rows
    }
}

我该如何改进以避免 运行 连接中断?

更新

得到以下答案后,我更新了我的代码 client.end() 而不是使用共享客户端:

// const results = await runDatabaseFunction(async (pool) => { ... })
const runDatabaseFunction = async function (functionToRun) {
  // Connect db
  const client = await pool.connect()
  // Run function
  const results = await functionToRun(client)
  // Release db
  await client.end()
  await client.release()
  return results
}

我认为问题来自 client = await pool.connect()

它似乎持有你的数据库。所以你需要断开你和数据库之间的连接。
如果您在上次获取数据后添加 await client.end(),则错误可能会消失。

就我而言,这种方式解决了问题。