为什么 Vercel 部署后 PostgreSQL 仍然存在 Idle 连接
为什么 Vercel 部署后 PostgreSQL 仍然存在 Idle 连接
如果你在 Vercel 上运行 Next.js, 并且直接连接 PostgreSQL,你很可能遇到过下面的错误:
remaining connection slots are reserved for roles with the SUPERUSER attribute
这个问题通常在重新部署后更容易出现,即使你的应用流量并不高。
常见现象
- PostgreSQL 中存在大量
idle状态的连接 - Vercel 实例已经关闭,但连接仍未释放
- 新请求无法获取数据库连接
- 手动终止连接只能暂时缓解问题
真正的原因
这是 Serverless 架构的正常行为。
Vercel 的工作方式大致如下:
- Vercel 根据请求启动多个 Serverless 实例
- 每个实例都会创建自己的数据库连接或连接池
- 实例结束后,无法保证数据库连接被优雅关闭
- PostgreSQL 会继续保留这些连接直到超时
结果就是:应用已经结束,但数据库连接仍然存在。
为什么会导致连接数耗尽
在托管 PostgreSQL 服务中,一部分连接被保留给系统和 SUPERUSER。
当 Serverless 实例频繁创建连接时,很容易用完普通用户可用的连接数, 从而触发该错误。
这不是数据库 bug,而是架构不匹配导致的问题。
PgBouncer 如何解决
PgBouncer 位于应用和数据库之间:
Vercel → PgBouncer → PostgreSQL
- 应用连接 PgBouncer,而不是直接连接数据库
- PgBouncer 使用少量真实数据库连接服务大量请求
- Serverless 实例关闭时,连接会被立即回收
- PostgreSQL 不再堆积 idle 连接
对于 Serverless 场景,推荐使用 transaction pooling 模式。
推荐配置
- 启用 PgBouncer
- 应用连接 PgBouncer 的 host 和 port
- Node.js 连接池设置为 1–2
idleTimeoutMillis设置为 5 秒左右- 设置
idle_in_transaction_session_timeout
总结
这个问题看起来像是 Vercel 的问题,但实际上是 Serverless + 直连数据库 的经典陷阱。
如果你在 Vercel 上使用 PostgreSQL, PgBouncer 是必需的,而不是可选的。
❤️ Support This Blog
If this post helped you, you can support my writing with a small donation. Thank you for reading.
Comments
Post a Comment