Mert Tosun
← Yazılar
PostgreSQL Connection Pooling: PgBouncer Kurulumu ve Go/Node.js ile Kullanımı

PostgreSQL Connection Pooling: PgBouncer Kurulumu ve Go/Node.js ile Kullanımı

Mert TosunBackend

Her uygulama örneği PostgreSQL’e ayrı bir bağlantı açmaya kalkarsa, veritabanı max_connections sınırına çok çabuk yaklaşırsınız. Connection pooling, özellikle PgBouncer ile, yüzlerce uygulama sürecini az sayıda gerçek DB bağlantısına çoklar.

Bu yazı PgBouncer kurulumu ve Go ile Node.js istemci tarafındaki pratik ayarlara odaklanır.

Sorun ne?

  • PostgreSQL her bağlantı için bellek ve süreç maliyeti taşır
  • Serverless veya çok replikalı Kubernetes ortamında bağlantı sayısı patlar
  • Kısa ömürlü istekler sürekli bağlantı açıp kapıyorsa gecikme artar

Çözüm: Uygulama → PgBouncer (havuz) → PostgreSQL.


PgBouncer pooling modları

  • Session: İstemci bağlantısı boyunca aynı sunucu bağlantısı (en uyumlu, en az paylaşım)
  • Transaction: Her transaction bitince bağlantı havuza döner (en yaygın, yüksek paylaşım)
  • Statement: Nadiren; çok kısıtlı kullanım

Çoğu web API için transaction pooling uygundur; prepared statement ve bazı session özellikleri kısıtlanabilir — ORM ayarlarını kontrol edin.


Kurulum (Docker örneği)

services:
  pgbouncer:
    image: edoburu/pgbouncer:latest
    environment:
      DATABASE_URL: postgres://user:pass@db:5432/appdb
      POOL_MODE: transaction
      MAX_CLIENT_CONN: 1000
      DEFAULT_POOL_SIZE: 25
    ports:
      - "6432:5432"

Gerçek üretimde userlist.txt, TLS ve auth_query gibi detaylar eklenir.


Go: database/sql

import "database/sql"
import _ "github.com/jackc/pgx/v5/stdlib"

db, err := sql.Open("pgx", os.Getenv("DATABASE_URL"))
if err != nil { log.Fatal(err) }
db.SetMaxOpenConns(20)       // uygulama içi havuz — PgBouncer ile küçük tutun
db.SetMaxIdleConns(5)
db.SetConnMaxLifetime(time.Hour)

PgBouncer arkasında uygulama tarafındaki MaxOpenConns değerini makul tutun; aksi halde istemci havuzu ile sunucu havuzu çift şişer.


Node.js: pg

const { Pool } = require('pg');
const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  max: 15,
  idleTimeoutMillis: 30000,
});

Transaction pooling kullanırken prepared statement sorunları yaşarsanız, ORM/pg sürücüsünde “disable prepared statements” seçeneklerine bakın (ör. Prisma, TypeORM dokümantasyonu).


İzleme ve ayar

  • SHOW POOLS, SHOW STATS (PgBouncer admin)
  • PostgreSQL’de pg_stat_activity
  • Uygulama: bağlantı bekleme süreleri ve timeout’lar

Özet

  • PgBouncer, özellikle transaction mode, yüksek eşzamanlılıkta PostgreSQL connection pooling için standart çözümdür.
  • Go ve Node.js tarafında istemci havuzunu küçük ve öngörülebilir tutun.
  • ORM + PgBouncer birlikte kullanılırken prepared statement davranışını test edin.

Mikroservislerde protokol seçimi için gRPC vs REST rehberiyle birlikte düşünmek faydalıdır: havuz hem HTTP hem gRPC servislerinde gerekebilir.