当前位置: 首页 > news >正文

在 Dokploy 中为 PostgreSQL 搭建 PgBouncer 数据库连接池(图文)

前言:为什么你需要一个连接池?

如果你正在使用 Node.js (尤其是像 Next.js 这样的框架) 配合 Prisma 操作 PostgreSQL 数据库,你很可能在某个阶段会遇到那个令人头疼的错误:“Error: Too many clients already”。这通常发生在应用并发量上升,或者在 Next.js 的构建 (next build) 阶段,因为它会尝试并行渲染多个页面,瞬间创建大量数据库连接。

虽然最直接的反应是增加 PostgreSQL 的 max_connections,但这只是一个临时的“创可贴”,它会消耗更多宝贵的服务器内存,并且无法从根本上解决连接风暴的问题。

一个更专业、更具扩展性的解决方案是在你的应用和数据库之间引入一个中间件——连接池工具PgBouncer 正是此领域的王者,它轻量、高效,能以极小的资源消耗管理成千上万的连接。

本指南将详细记录我们如何在 Dokploy 平台上,为一个正在运行的 PostgreSQL 数据库和一个需要进行静态站点生成 (SSG) 的 Next.js 应用,成功搭建并配置 PgBouncer 服务。我们将这个过程中的每一步、遇到的每一个坑、以及最终的解决方案都毫无保留地分享出来。

核心架构:我们要做什么?

我们的目标非常明确:将应用架构从“直连”模式升级为通过 PgBouncer 连接池管理的“中间人”模式。

部署前架构 (直连模式):

[Next.js App] —> [PostgreSQL Database]

  • 问题: 应用的每一次数据库操作都可能创建一个新的连接,在高并发或构建时极易耗尽数据库资源。

部署后架构 (连接池模式):

[Next.js App] —> [PgBouncer Pooler] —> [PostgreSQL Database]

  • 优势: Next.js 应用将所有连接请求都发送给 PgBouncer。PgBouncer 维护一个与 PostgreSQL 之间的小而稳定的连接池,高效地复用这些连接来处理大量请求。数据库本身将得到极大的保护。

Step 1: 创建 PgBouncer 服务骨架

我们的第一步是在 Dokploy 中创建一个新的应用,用于承载 PgBouncer。

  1. 在 Dokploy 仪表盘,点击 “Add new” -> “Application”。
  2. 在 “Provider” 部分,选择 Docker 作为来源。
  3. Docker Image 输入框中,填入镜像名称:edoburu/pgbouncer
  4. 此时先不要部署,直接进入下一步配置。
    在这里插入图片描述

Step 2: 暴露所需端口

为了让服务之间可以通过网络互相访问,我们需要将 PostgreSQL 和 PgBouncer 的端口都映射到宿主机上。

  1. 暴露 PostgreSQL 端口:

    • 进入你的 PostgreSQL 数据库服务的配置页面。
    • 导航到 Advanced -> Ports
    • 添加一条规则,将数据库的真实端口(例如 5633)映射出来。
      • Published Port: 5633
      • Published Port Mode: Host
      • Target Port: 5633
    • 保存并 Redeploy PostgreSQL 服务。
  2. 暴露 PgBouncer 端口:

    • 回到我们刚刚创建的 PgBouncer 服务的配置页面。
    • 导航到 Advanced -> Ports
    • 添加一条规则,将 PgBouncer 的监听端口 6432 映射出来。
      • Published Port: 6432
      • Published Port Mode: Host
      • Target Port: 6432
    • 保存设置。

[图片占位符:Dokploy 中为 PgBouncer 服务配置端口映射的弹窗界面]
在这里插入图片描述

Step 3: 准备并挂载 PgBouncer 配置文件

现在,我们需要为 PgBouncer 提供它的“灵魂”——配置文件。

1. 在本地准备配置文件

在这里插入图片描述
在这里插入图片描述

  • pgbouncer.ini (主配置文件): 创建一个文本文件,填入以下内容。

    [databases]
    # 定义数据库连接。这里的 key (YOUR_DATABASE_NAME) 最好和真实的 dbname 保持一致。
    # host 设置为你的服务器公网IP,port 设置为你的 PostgreSQL 真实端口。
    YOUR_DATABASE_NAME = host=YOUR_SERVER_PUBLIC_IP port=YOUR_POSTGRES_PORT dbname=YOUR_DATABASE_NAME[pgbouncer]
    # 监听所有网络接口,允许来自 Docker 外部和内部的连接
    listen_addr = *
    # PgBouncer 自身的监听端口,给 Next.js 应用连接
    listen_port = 6432# 认证方式必须是 md5,并且需要指定用户列表文件
    auth_type = md5
    auth_file = /etc/pgbouncer/userlist.txt# 定义哪些用户拥有管理和查看统计的权限
    admin_users = YOUR_DATABASE_USERNAME
    stats_users = YOUR_DATABASE_USERNAME# 连接池模式。transaction 是对大多数应用最安全、最推荐的模式
    pool_mode = transaction# 池大小等性能配置
    default_pool_size = 20
    max_client_conn = 1000# pgbouncer 进程的 pid 文件路径
    pidfile = /var/run/pgbouncer/pgbouncer.pid
    
  • userlist.txt (认证文件): 创建第二个文本文件,定义允许连接的用户名和密码。

    # 格式: "用户名" "密码"
    # 必须使用英文双引号将用户名和密码括起来,中间用一个空格隔开。
    "YOUR_DATABASE_USERNAME" "YOUR_DATABASE_PASSWORD"
    
2. 在 Dokploy 中挂载配置文件
  • 回到 PgBouncer 服务Advanced -> Volumes 设置区域。
  • 添加两个 File Mount 类型的挂载:
    • 第一个: 将 pgbouncer.ini全部内容粘贴进去,Mount Path 设置为 /etc/pgbouncer/pgbouncer.ini
    • 第二个: 将 userlist.txt全部内容粘贴进去,Mount Path 设置为 /etc/pgbouncer/userlist.txt

Step 4: 配置启动命令并部署 PgBouncer

  1. PgBouncer 服务Advanced -> Run Command 区域,明确告诉容器如何启动。
    • Command: pgbouncer /etc/pgbouncer/pgbouncer.ini
  2. 完成所有配置后,点击页面右上角的 Deploy 按钮部署 PgBouncer 服务。
  3. 检查 PgBouncer 的日志,确保它已正常启动,并且没有 broken auth fileconnect failed 等错误。

在这里插入图片描述
最后回到 General 中点击 Deploy 就可以部署成功了:

在这里插入图片描述

Step 5: 更新 Next.js 应用配置(决胜一步)

现在 PgBouncer 服务已经通过公网 IP 和指定端口(6432)完全就绪,我们可以直接让 Next.js 应用连接这个公开的地址。这个方法可以同时解决构建和运行时的连接问题。

  1. 进入你的 Next.js 应用在 Dokploy 的配置页面。

  2. 导航到 Environment 标签页。

  3. 找到 DATABASE_URL 这个环境变量(如果没有就新建一个)。

  4. 将其值设置为指向 PgBouncer 的公网地址

    postgresql://YOUR_DATABASE_USERNAME:YOUR_DATABASE_PASSWORD@YOUR_SERVER_PUBLIC_IP:6432/YOUR_DATABASE_NAME?pgbouncer=true
    

    重要: 请确保这里的 YOUR_SERVER_PUBLIC_IP 是您服务器的公网 IP,端口是 PgBouncer 的端口 6432

[图片占位符:Next.js 应用中配置 DATABASE_URL 环境变量的截图]

  1. 确认构建命令为默认值:在 “General” 标签页,确保 “Build Command” 是简单的 pnpm run buildnpm run build,不带任何 DATABASE_URL= 的前缀。
  2. 保存所有修改,然后点击 Deploy 部署你的 Next.js 应用。
  3. ?pgbouncer=true 是一个专门的 “兼容模式”开关,你用它来明确地告知 Prisma:“注意,你现在连接的不是一个真正的 PostgreSQL 数据库,而是一个 PgBouncer 连接池!请调整你的行为模式。”

总结

恭喜你!如果一切顺利,你的应用现在应该已经成功构建并运行起来了。

通过这次实践,我们不仅解决了一个棘手的数据库连接问题,还掌握了在类 PaaS 平台(如 Dokploy)上进行复杂服务编排的关键技能。我们学会了如何:

  • 使用 PgBouncer 管理连接池。
  • 通过端口映射和服务名进行服务间通信。
  • 利用文件挂载注入自定义配置。
  • 通过统一使用公网地址,快速解决在 CI/CD 流程中访问数据库的难题。

现在,你的应用架构变得更加健壮、高效且具备弹性,能够从容应对未来的流量挑战。

http://www.dtcms.com/a/267812.html

相关文章:

  • 【influxdb3】如何使用 SQL 对时间序列数据进行聚合查询
  • Golang读取ZIP压缩包并显示Gin静态html网站
  • 51c大模型~合集150
  • 大型语言模型中的自动化思维链提示
  • unity校招岗面试题 天津某场 深圳某场
  • spring中@Transactional注解和事务的实战理解附代码
  • 蓝凌EKP产品:Hibernate懒加载检测与开发助手
  • LoRaWAN的设备类型有哪几种?
  • ABP VNext + Tye:本地微服务编排与调试
  • 1.线性神经网络--线性回归
  • Windows深色模式助手,定时自动切换
  • 热方程初边值问题解法
  • Qt之修改纯色图片的颜色
  • token设计方案
  • 大话网络协议 - HTTP不同版本的演进及其区别
  • 基于Excel的数据分析思维与分析方法
  • Java poi-tl 使用 word 模板 生成 word
  • 人工智能之数学基础:线性回归算法的矩阵参数求导
  • dubbo源码学习2-dubbo协议源码分析
  • C++:编译QXlsx库过程
  • 咕咚运动启动时弹出广告
  • Go语言--语法基础6--基本数据类型--切片类型
  • 【学习篇】SQL复杂查询学习
  • D3 面试题100道之(61-80)
  • React 英语单词消消乐一款专为英语学习设计的互动式记忆游戏
  • Flink ClickHouse 连接器:实现 Flink 与 ClickHouse 无缝对接
  • Scala 简介
  • 探索实现C++ STL容器适配器:优先队列priority_queue
  • 三维目标检测|Iou3D 代码解读一
  • [Qt] visual studio code 安装 Qt插件