写在前面:
在Linux服务器部署PostgreSQL数据库(尤其搭配Dify等高频连接类应用)时,"连接数超限"是最常见且棘手的问题之一------轻则导致应用无法建立新连接、接口报错,重则造成数据库僵死、服务不可用,就像此前遇到的"无法登录PostgreSQL、kill进程权限不足"的困境,本质都是连接管理失控所致。PostgreSQL默认的连接数配置有限,且每一个数据库连接都会占用一定的系统内存和资源,当高并发请求来袭或应用存在连接泄漏时,很容易突破连接上限,引发服务故障。
一、PgBouncer介绍
1、简要介绍
PgBouncer作为一款轻量级、高性能的PostgreSQL连接池中间件,正是解决这一痛点的核心工具。它通过"连接复用"机制,将应用发起的大量连接进行集中管理、动态分配,让有限的PostgreSQL原生连接能够支撑数千甚至上万的客户端请求,从根源上杜绝连接数超限问题,同时降低数据库的资源消耗,提升服务稳定性。相较于单纯调大PostgreSQL的max_connections参数,PgBouncer无需占用过多系统资源,配置灵活且部署便捷,是生产环境中优化PostgreSQL连接管理的首选方案。
官方网址:PgBouncer - lightweight connection pooler for PostgreSQL
性能对比可参考:PgBouncer实战指南:如何优化PostgreSQL连接池性能与稳定性_ss78901-腾讯云开发者社区
2、数据流转工作原理
-
接入转发: 所有业务程序、项目(Dify、后台服务、接口服务等)不再直连 PG,统一连接PgBouncer 代理端口。
-
**连接池收纳:**PgBouncer 接收海量客户端连接,进行统一缓存、排队、管控,限制并发接入量。
-
连接复用: 按照事务级 / 会话级复用空闲数据库物理连接,客户端断开不销毁 PG 真实连接。
-
**下发执行:**将精简后的有效请求转发至后端 PostgreSQL 执行 SQL。
-
**回收归还:**请求 / 事务结束后,立刻把 PG 物理连接回收至连接池,供其他客户端复用。
3、直连 VS PgBouncer 对比简图
传统直连(易爆连接)
应用1 → PG直连
应用2 → PG直连
应用3 → PG直连
...
连接快速打满 → 报错 too many connections
PgBouncer 代理(稳定限流)
应用1 ──┐
应用2 ──┤
应用3 ──┼──→ PgBouncer ──少量固定连接──→ PostgreSQL
应用4 ──┘
二、前置准备
1、环境说明
-
数据库:PostgreSQL(默认端口 5432)
-
连接池:PgBouncer(统一转发连接,收敛连接数)
-
可视化:PgBouncerHero 网页面板 + Prometheus+Grafana 监控
-
系统:Linux Ubuntu
2、开放防火墙端口
端口6432为PgBouncer 的代理端口 (应用连接使用),端口8090为可视化/监控端口 (Prometheus/Grafana/Exporter),sudo ufw reload为重载防火墙规则。
sudo ufw allow 6432/tcp
sudo ufw allow 8090/tcp
sudo ufw reload

三、安装部署 PgBouncer
1、安装与初始化
sudo apt update
sudo apt install -y pgbouncer

创建目录(记录日志文件和pgBouncer 运行的进程号):
sudo mkdir -p /var/log/pgbouncer
sudo mkdir -p /var/run/pgbouncer
修改目录所有者(默认为pg数据库的postgre用户):
sudo chown -R postgres:postgres /var/log/pgbouncer
sudo chown -R postgres:postgres /var/run/pgbouncer
2、配置 PgBouncer
sudo nano /etc/pgbouncer/pgbouncer.ini
打开以后把里面内容全部替换成下面这段:
[databases]
my_db = host=127.0.0.1 port=5432 dbname=production_db
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
admin_users = postgres
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 50
min_pool_size = 10
server_idle_timeout = 600
logfile = /var/log/pgbouncer/pgbouncer.log
pidfile = /var/run/pgbouncer/pgbouncer.pid
stats_users = postgres
点击Ctrl+O保存,回车,点击Ctrl+X退出。
3、配置文件解释说明
(1)[databases]:第一后端目标
这部分告诉 PgBouncer:"当有人连接我时,你应该把这些流量转发到哪里"。
-
my_db(别名) :这是你在连接数据库时使用的名称。例如,你提供的连接字符串是...:6432/my_db,PgBouncer 会解析到后面定义的参数。 -
host=127.0.0.1 port=5432:这是真实的数据库服务地址。 -
dbname=production_db:这是数据库内部的真实库名。通过别名映射,你甚至可以实现"应用连接的是库A,实际存取的是库B"的隐藏效果。
(2)[pgbouncer]:核心运行逻辑
监听与认证
-
listen_addr & listen_port:0.0.0.0 表示允许任意 IP 连接(生产环境建议限制 IP),6432 是对外提供的服务入口。
-
auth_type = md5:强制使用 MD5 密码加密校验,确保安全性。
-
auth_file:指向用户列表文件,PgBouncer 在这里匹配用户名和加密后的密码。
-
admin_users = postgres:拥有管理权限的用户,通过 psql -p 6432 -U postgres -d pgbouncer 登录后,可以使用如 SHOW POOLS; 或 RELOAD; 等管理指令。
池化逻辑 (核心)
-
pool_mode = transaction:这是 PgBouncer 的精髓。
-
在 transaction 模式下,连接池只在事务级别复用。这意味着一个客户端连接执行完一条 SQL(或一个事务)后,该数据库连接就会被释放,迅速给其他客户端使用。
-
区别:如果设置成 session,一个客户端会占用一个连接直到断开,这样依然会很快耗尽后端连接。
连接池调优参数
-
max_client_conn = 1000:这是你系统能承受的应用并发上限。如果第 1001 个连接请求进来,PgBouncer 会拒绝它,保护数据库不被压垮。
-
default_pool_size = 50:这是对数据库真实的"负载阀门"。不管前面有 1000 个请求,后端只会建立 50 个物理长连接,这 50 个连接在 1000 个请求间快速切换。
-
min_pool_size = 10:预热池。系统启动时会保持 10 个连接,避免流量突然到来时频繁创建新连接带来的 TCP 握手开销。
-
server_idle_timeout = 600:如果后端连接闲置超过 600 秒(10分钟),PgBouncer 会主动断开它们,释放数据库端的资源。
系统维护与监控配置
-
logfile & pidfile:这是运行期的轨迹追踪。pidfile 确保同一时间只有一个 PgBouncer 进程在运行,防止配置冲突或资源竞争。
-
stats_users = postgres:这非常重要。只有在这里指定的账号,登录 pgbouncer 数据库后,才能查看当前的连接状态、等待数(cl_waiting)等信息。
4、配置数据库账号密码
sudo nano /etc/pgbouncer/userlist.txt
在这里写的用户名,必须是前面填写的dbname=production_db数据库中实际存在的数据库角色(Role/User),但当你需要通过 PgBouncer 以数据库超级管理员身份进行某些维护操作,或者进行监控采集时还可以填写postgres用户,postgres用户拥有最高权限,如果泄露,风险极高。写入的示例如下:
"postgres" "你的密码"
点击Ctrl+O保存,回车,点击Ctrl+X退出。
5、启动 PgBouncer
sudo systemctl restart pgbouncer
sudo systemctl enable pgbouncer
sudo systemctl status pgbouncer
看到 active (running) 就是成功运行。

6、测试连接
所有人不再直连 5432,统一连接:
-
IP:数据库服务器 IP
-
端口:6432
-
账号密码库名不变
输入以下指令测试:
psql -h 127.0.0.1 -p 6432 -U postgres -d postgres
注意:这里的-U postgres表示以"哪个账号"身份来发起连接的,-d postgres告诉 PostgreSQL,你想进入哪一个具体的数据库。psql -U 用户名 -d 数据库名中的这两个参数,必须在你的 PgBouncer 配置文件 ( /etc/pgbouncer/pgbouncer.ini**)** 和 用户认证文件 ( /etc/pgbouncer/userlist.txt**)** 中都能找到对应的记录。
如果这个测试通过了,说明你的 PgBouncer 通道完全通畅。
四、PgBouncer 自带命令行管理
1、连接管理控制台
psql -h 127.0.0.1 -p 6432 -U postgres pgbouncer

2、常用的查询命令
(1)监控与状态查询
SHOW POOLS; -- 查看连接池概况(观察 cl_waiting 是否有积压)
SHOW CLIENTS; -- 查看所有接入的客户端连接(含IP、连接时长)
SHOW SERVERS; -- 查看 PgBouncer 与后端 PG 的连接状态
SHOW STATS; -- 查看流量、查询吞吐量及平均延迟统计
SHOW LISTS; -- 查看当前系统分配的各种资源列表(如池、客户端、服务器数)
SHOW POOLS;
作用:查看当前所有连接池的概况。
关键指标:
-
cl_active:当前正在执行 SQL 的客户端连接数。
-
cl_waiting:正在排队等待数据库连接的客户端数(如果数值长期大于 0,说明连接池不够用了)。
-
sv_active:当前正在与后端数据库通信的连接数。
-
sv_idle:后端数据库中处于空闲状态的连接数。
SHOW STATS;
作用:查看全局统计数据(自启动以来的累计值)。
- 关注点:avg_query_time(平均查询耗时)和 total_xact_time(事务总耗时),这能帮你评估性能瓶颈。
SHOW CLIENTS;
作用:查看所有当前连接到 PgBouncer 的客户端详情(包括 IP、连接时间、请求状态)。
SHOW SERVERS;
作用:查看 PgBouncer 连接到后端数据库的连接状态(可以看到哪些连接是空闲的、哪些正在处理事务)。
(2)配置管理
SHOW CONFIG; -- 查看当前生效的全部配置参数
RELOAD; -- 热加载配置文件(无需重启服务,修改 .ini 后执行)
SHOW CONFIG;
作用:列出当前 PgBouncer 正在使用的所有配置参数及其当前值。当你修改了 pgbouncer.ini 后,可以用此命令确认配置是否生效。
SHOW VERSION;
作用:查看当前运行的 PgBouncer 版本。
(3)维护与控制
PAUSE; -- 暂停所有连接池(断开后端连接,挂起客户端请求,用于维护)
RESUME; -- 恢复暂停的连接池
KILL <数据库名>; -- 强制断开并关闭与指定数据库的所有后端连接
SHUTDOWN; -- 关闭 PgBouncer 服务进程
RELOAD;
作用:重新加载配置文件 (pgbouncer.ini)。如果你修改了配置,无需重启进程,执行该命令即可热加载。
PAUSE;
作用:暂停所有连接池。PgBouncer 会尝试断开与后端数据库的连接,并将后续进来的客户端连接挂起。常用于数据库维护操作前。
RESUME;
作用:恢复被 PAUSE 挂起的连接池。
KILL <数据库名>;
作用:强制断开与指定数据库相关的所有服务器连接。注意:这是强力操作,会丢弃当前正在进行的未提交事务。
(4)异常处理
-- 1. 先查找异常连接的 PID(在 SHOW CLIENTS 的输出结果中查看)
SHOW CLIENTS;
-- 2. 使用 KILL 命令踢出(注意:PgBouncer 中 KILL 后接的是连接地址或特定标识,非系统进程ID)
KILL <连接ID或数据库名>;
五、部署可视化网页面板 PgBouncerHero
说明:
这一部分实现
Linux 上的 PgBouncer → Windows 上部署 PgBouncerHero 网页面板 → 远程连接监控
PgBouncerHero 本质上是:一个连接 PgBouncer Admin Console 的 Rails Web UI
它会执行:SHOW STATS;SHOW POOLS;SHOW CLIENTS;SHOW SERVERS;然后可视化展示。
1、准备工作
(1)改 pgbouncer.ini(Linux)
[pgbouncer]
listen_addr = 0.0.0.0 ; 允许所有IP连,不要只写 localhost
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
admin_users = postgres ; 后面网页要用这个账号登录管理
(2)防火墙开放 6432 端口(Linux)
sudo ufw allow 6432/tcp
(3)userlist.txt 确保有管理员密码(Linux)
# 格式:"用户名" "密码"
"postgres" "你的postgres密码"
(4)重启pgbouncer
sudo systemctl restart pgbouncer
(5)需要的环境
-
Windows 11
-
WSL2(Ubuntu)
-
Docker(用于 PgBouncer)
2、WSL 安装 Ruby + PgBouncerHero
(1)安装 Ruby环境
在WSL或者Ubuntu内执行:
sudo apt update
sudo apt install -y \
git \
curl \
build-essential \
libssl-dev \
zlib1g-dev \
libyaml-dev \
libreadline-dev \
libpq-dev
安装rbenv:
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/main/bin/rbenv-installer | bash
如果失败尝试以下方法:
git clone https://ghfast.top/https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
git clone https://mirror.ghproxy.com/https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
然后配置环境变量:
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init - bash)"' >> ~/.bashrc
source ~/.bashrc
rbenv安装验证:
rbenv --version

查看可以安装的Ruby版本:
rbenv install -l

这里选择安装3.4.9版本:
rbenv install 3.4.9
需要等待一会,安装完成后:
rbenv global 3.4.9

验证安装:
ruby -v

(3)安装pgbouncerhero
转移到pgbouncerhero所在的文件夹,运行以下命令:
cd /mnt/e/pgbouncer/pgbouncerhero
bundle install
看到Bundle complete!即为安装依赖成功。

验证安装:
bundle list | grep pgbouncerhero

说明 gem 已安装成功。
(4)测试连接
在WSL中运行(换成你的服务器IP):
psql -h 172.xx.xx.xxx -p 6432 -U postgres pgbouncer
执行:
SHOW DATABASES;
若看到你之前在pgbouncer中配置的数据库名称,则说明PgBouncer正常。
3、启动PgBouncerHero
(1)设置环境变量
export PGBOUNCERHERO_DATABASE_URL="postgres://postgres:password@172.XX.XX.XX:6432/pgbouncer"
(2)启动Hero
bundle exec rackup test/dummy/config.ru -p 3000 -o 0.0.0.0
(3)访问UI
浏览器打开:http://localhost:3000/pgbouncerhero

4、PgBouncerHero可视化界面介绍

(1)Databases (数据库概览)
含义:显示了当前配置的哪些数据库名(数据库别名)被允许访问,以及它们分别映射到哪个物理后端数据库。
关键列:
-
Name: 数据库的逻辑名称。
-
Host/Port: 实际指向的后端 PostgreSQL 服务器地址和端口。
-
Database: 后端实际的物理数据库名。
-
Force_user: 是否强制使用特定用户连接后端,忽略客户端传入的用户名(常用于连接池共享)。
-
作用:用于核对连接的路由配置是否正确,确保流量被导向了预期的数据库。
(2)Pools (连接池状态 - 最重要)
含义:描述了"客户端到 PgBouncer"与"PgBouncer 到 PostgreSQL"之间的连接桥梁状态。
关键列(参考上一条回复的指标):
-
Cl_active / Cl_waiting: 客户端的流量压力。
-
Sv_active / Sv_idle: 后端数据库的承载负载。
(3)Clients (客户端连接)
含义:列出所有已连接到 PgBouncer 的应用端(如 Web 服务、后台任务)的连接信息。
关键列:
-
Caddr: 客户端的 IP 地址和端口。
-
User: 连接使用的数据库用户名。
-
Database: 正在访问的数据库。
-
State: 客户端状态(如
active表示正在执行查询,idle表示等待中)。 -
Wait_time: 该连接进入等待状态的时间(如果是 0 表示正在处理中)。
(4)Stats (统计信息)
含义:展示了系统级别的流量处理能力和性能开销。
关键指标:
-
Total_requests: 累计处理的 SQL 请求总数。
-
Total_query_time: 所有查询累计耗时(微秒)。
-
Avg_query_time: 平均每个查询的耗时(评估数据库性能的关键指标)。
-
Total_received / Total_sent: 累计流量统计。
(5)Configuration (配置参数)
含义:列出了 pgbouncer.ini 文件中设置的所有运行参数,以及运行时生效的配置。
关键参数:
-
pool_mode: 运行模式(
transaction,session, 或statement)。 -
max_client_conn: 允许的最大客户端连接数。
-
default_pool_size: 每个连接池默认的后端连接上限。
-
server_idle_timeout: 空闲服务器连接的回收时间。
欢迎交流!!🌹🌹
参考内容: