如何在搭载PostgreSQL插件的Dokku实例上安装PgBouncer?
你的场景非常典型:后台任务框架(Sidekiq/Delayed Job)的每个Worker都会创建独立的数据库连接,加上Puma的工作线程连接,很快就会耗尽PostgreSQL的默认连接数。PgBouncer作为连接池中间件,能帮你把应用侧的连接复用,大幅减少实际打到PostgreSQL的连接数量,完美解决这个问题。下面针对你的Dokku 0.6.5环境,给出两种最优方案:
方案一:升级Dokku到0.15.0+,使用Heroku PgBouncer Buildpack
这是你提到的思路,也是最贴合Heroku生态(和你现有的Rails配置习惯匹配)的方案,步骤如下:
安全升级Dokku
先备份你的Dokku应用和数据库,避免升级出问题:# 备份应用 dokku apps:backup create <你的应用名> # 备份PostgreSQL数据库 dokku postgres:backup <你的数据库名>然后按照官方流程升级到0.15.0(或更高稳定版):
wget https://raw.githubusercontent.com/dokku/dokku/v0.15.0/bootstrap.sh sudo DOKKU_TAG=v0.15.0 bash bootstrap.sh升级完成后验证版本:
dokku --version启用PgBouncer Buildpack
在你的Rails项目根目录添加.buildpacks文件,内容如下(先加PgBouncer buildpack,再加Ruby buildpack):https://github.com/heroku/heroku-buildpack-pgbouncer.git https://github.com/heroku/heroku-buildpack-ruby.git然后推送代码到Dokku:
git add .buildpacks git commit -m "Add PgBouncer buildpack" git push dokku main配置PgBouncer核心参数
设置PgBouncer的关键环境变量,适配Rails场景:# 设置连接池模式(transaction模式最适合Rails,性能最优) dokku config:set <你的应用名> PGBOUNCER_POOL_MODE=transaction # 设置PgBouncer的最大客户端连接数(支持大量应用侧连接) dokku config:set <你的应用名> PGBOUNCER_MAX_CLIENT_CONN=1000 # 设置默认连接池大小(建议比PostgreSQL max_connections略小) dokku config:set <你的应用名> PGBOUNCER_DEFAULT_POOL_SIZE=20 # 切换应用到PgBouncer连接 dokku config:set <你的应用名> DATABASE_URL=$(dokku postgres:info <你的数据库名> | grep "DSN" | awk '{print $2}')_pgbouncer注意:
DATABASE_URL末尾添加_pgbouncer是Heroku buildpack的约定,用来自动路由到PgBouncer服务。调整Rails和后台任务的连接池
现在可以适当调大应用侧的连接池(PgBouncer会负责复用),修改config/database.yml:production: adapter: postgresql pool: 20 url: <%= ENV['DATABASE_URL'] %>对于Sidekiq,修改
config/sidekiq.yml::concurrency: 20 :timeout: 30 :pool: 20
方案二:不升级Dokku,使用Dokku PgBouncer插件
如果暂时不想升级Dokku,你可以使用社区维护的Dokku PgBouncer插件,步骤更简洁:
安装PgBouncer插件
sudo dokku plugin:install https://github.com/dokku/dokku-pgbouncer.git pgbouncer关联数据库与应用
执行命令后会自动替换应用的DATABASE_URL为PgBouncer连接:dokku pgbouncer:link <你的数据库名> <你的应用名>配置PgBouncer参数
适配Rails场景调整核心参数:# 设置transaction连接模式 dokku pgbouncer:set <你的应用名> pool-mode transaction # 设置默认连接池大小 dokku pgbouncer:set <你的应用名> default-pool-size 20 # 设置最大客户端连接数 dokku pgbouncer:set <你的应用名> max-client-conn 1000重启应用生效
dokku ps:restart <你的应用名>
关键配置注意事项
- 连接模式选择:
transaction模式是Rails应用的最优选择,它会在事务结束后立即释放连接,最大化复用率。 - 连接池大小控制:PgBouncer的
default-pool-size建议设置为PostgreSQLmax_connections(默认100)的1/5~1/4,避免压垮数据库。 - 监控连接状态:部署后可以通过以下命令验证效果:
# 查看PostgreSQL实际连接数 dokku postgres:connect <你的数据库名> SELECT count(*) FROM pg_stat_activity; # 查看PgBouncer连接统计 dokku pgbouncer:stats <你的应用名>
内容的提问来源于stack exchange,提问作者C. Short

