Du är generellt sett på rätt spår och din analys verkar korrekt. Några kommentarer:
Alternativ 2 (att ta bort keepalives) hjälper till att ta bort lediga anslutningar i Npgsqls pool som har brutits. Som du har skrivit kommer din applikation fortfarande att misslyckas (eftersom vissa dåliga lediga anslutningar kanske inte tas bort i tid). Det finns ingen speciell anledning att tro att detta skulle orsaka ytterligare problem - det här borde vara ganska säkert att slå på.
Alternativ 3 är verkligen problematiskt för perf, eftersom en TCP-anslutning till pgbouncer skulle behöva upprättas varje gång en databasanslutning behövs. Det kommer inte heller att tillhandahålla en 100 % felsäker mekanism, eftersom pgbouncer fortfarande kan hoppa av medan en anslutning används.
I slutet av dagen frågar du om motståndskraft inför godtyckliga nätverks-/serverfel, vilket inte är lätt att uppnå. Det enda 100% pålitliga sättet att hantera detta är i din applikation, via ett dedikerat lager som skulle försöka igen när ett tillfälligt undantag inträffar. Du kanske vill titta på Polly
, och notera att Npgsql hjälper oss lite genom att exponera en IsTransient
undantag som kan användas som en trigger för att försöka igen (Entity Framework Core inkluderar också en liknande "försök igen strategi"). Om du går in på den här vägen, notera att transaktioner är särskilt svåra att hantera korrekt.