Microservice unter Last stabilisiert
PgBouncer & Import‑Optimierung sichern zuverlässige Verfügbarkeit trotz wachsender Datenmengen.
Ergebnisse
- Importlaufzeiten stabilisiert, keine Timeouts unter Produktionslast
- Datenbank‑Verbindungslimits eingehalten (Pool‑gesteuert)
- Deutlich robustere Verfügbarkeit des Dienstes
Messung über Laufzeit‑Logs & DB‑Metriken (z. B. aktive Verbindungen, Fehlerquoten).
Ausgangslage
Ein datenintensiver Go‑Microservice erzeugte unter Last zu viele Datenbankverbindungen. Die Folge waren Verbindungsabbrüche und gelegentliche Timeouts im Produktivbetrieb – insbesondere bei parallelen Importen und Backfill‑Jobs.
Weg zur Stabilität
Wir haben die Importstrategie entzerrt (Batching & Backpressure), Connection Pooling über PgBouncer eingeführt und Hot‑Paths in SQL überarbeitet. Zusätzlich wurden worker‑seitige Concurrency‑Limits gesetzt und die Telemetrie ausgebaut, um Kapazitäten sichtbar zu machen.
Konkret (vereinfacht)
# pgbouncer.ini
[databases]
appdb = host=postgres port=5432 dbname=appdb
[pgbouncer]
listen_port = 6432
pool_mode = transaction
max_client_conn = 200
default_pool_size = 20
server_reset_query = DISCARD ALL
// Go (database/sql) – DSN zeigt auf PgBouncer bei Port 6432
sql.Open("pgx", os.Getenv("DATABASE_URL"))
// Poolgrenzen an die DB‑Kapazität anpassen
DB.SetMaxOpenConns(20)
DB.SetMaxIdleConns(20)
DB.SetConnMaxLifetime(5 * time.Minute)
Ziel: konstante Last auf der Datenbank, kurze Transaktionen, vorhersehbare Parallelität – statt ungebremster Verbindungsflut.
Analyse & Messung
- Baseline über
pg_stat_activity
& Logs (Peak‑Verbindungen, Wartesituationen) - Vergleich vor/nach Pooling (Timeouts, Fehlerquoten, Importdauer)
- Dashboards & Alarme für Verbindungsauslastung und Fehler
Betrieb & Qualität
- Feature‑Toggle & Shadow‑Run der neuen Importpfade vor Umschaltung
- Readiness/Liveness‑Probes auf Downstream‑Abhängigkeiten
- Rollback‑Pfad pro Umgebung (sichere Umschaltpunkte)
Was heute anders ist
Die Importprozesse laufen planbar durch, die Verbindungen bleiben unterhalb der erlaubten Limits, und der Dienst ist unter Last deutlich robuster. Erweiterungen können schrittweise aktiviert und über Metriken überwacht werden.