Generalnie jesteś na dobrej drodze, a Twoja analiza wydaje się dokładna. Kilka komentarzy:
Opcja 2 (wyłączanie podtrzymania aktywności) pomoże usunąć nieaktywne połączenia z puli Npgsql, które zostały zerwane. Jak już napisałeś, twoja aplikacja nadal będzie miała pewne awarie (ponieważ niektóre złe bezczynne połączenia mogą nie zostać usunięte na czas). Nie ma żadnego szczególnego powodu, by sądzić, że spowoduje to dalsze problemy – włączenie powinno być całkiem bezpieczne.
Opcja 3 jest rzeczywiście problematyczna dla wydajności, ponieważ połączenie TCP z pgbouncer musiałoby być nawiązywane za każdym razem, gdy potrzebne jest połączenie z bazą danych. Nie zapewni również mechanizmu w 100% odpornego na awarie, ponieważ pgbouncer może nadal wypadać, gdy połączenie jest w użyciu.
Pod koniec dnia pytasz o odporność na arbitralną awarię sieci/serwera, co nie jest rzeczą łatwą do osiągnięcia. Jedynym w 100% niezawodnym sposobem radzenia sobie z tym jest aplikacja, za pośrednictwem dedykowanej warstwy, która będzie ponawiać operacje, gdy wystąpi przejściowy wyjątek. Możesz spojrzeć na Polly
i zauważ, że Npgsql pomaga nam trochę, ujawniając IsTransient
wyjątek, który może być używany jako wyzwalacz do ponawiania próby (Entity Framework Core zawiera również podobną "strategię ponawiania prób"). Jeśli pójdziesz tą ścieżką, pamiętaj, że transakcje są szczególnie trudne do prawidłowej obsługi.