wake-up-neo.com

Zeitüberschreitungen beim Herstellen einer Verbindung zu einer Postgres-Datenbank in Amazon RDS über Azure

Ich erhalte die folgende Ausnahme in meiner Anwendung, nachdem eine Datenbankverbindung längere Zeit nicht verwendet wurde:

... An I/O error occured while sending to the backend.; nested exception is org.postgresql.util.PSQLException: An I/O error occured while sending to the backend.] with root cause

    Java.net.SocketException: Operation timed out
        at Java.net.SocketInputStream.socketRead0(Native Method)

Das gleiche Problem tritt in psql auf und ich habe keine Probleme mit der Verbindung zu einer lokalen Datenbank, daher bin ich mir ziemlich sicher, dass das Problem auf RDS liegt.

psql=> select 'ok';
SSL SYSCALL error: Operation timed out
psql=> select 'ok';
SSL SYSCALL error: EOF detected
The connection to the server was lost. Attempting reset: Succeeded.

Ich habe diese andere Frage gefunden, die auf eine Umgehung hinweist, die die Situation verbessert hat (Timeouts dauern jetzt viel länger), aber nicht behoben.

Ich verwende Spring Boot mit JDBC (Tomcat Connection Pooling) und JDBCTemplate.

Gibt es eine Problemumgehung oder ein Problem? Möglicherweise muss der Verbindungspool getestet und erneut eine Verbindung hergestellt werden. Wie mache ich das in dieser Umgebung?

EDIT: Dies ist meine Verbindungszeichenfolge

jdbc:postgresql://myhost.c2estvxozjm3.eu-west-1.rds.amazonaws.com/dashboard?tcpKeepAlive=true

LÖSUNG:

Die TCP_KeepAlive-Parameter des RDS-Servers wurden wie in der ausgewählten Antwort vorgeschlagen bearbeitet. Die Parameter, die ich verwende, sind:

tcp_keepalives_count      5
tcp_keepalives_idle     200
tcp_keepalives_interval 200
16

Es sieht so aus, als ob etwas - vielleicht ein NAT -Router an Ihrem Ende, vielleicht etwas an AWS-Ende - Verbindungs-Tracking ist und Verbindungen nach einer Weile vergisst.

Ich schlage vor, TCP Keepalives aktivieren . Sie können sie möglicherweise serverseitig in der AWS RDS-Konfiguration aktivieren. Wenn nicht, können Sie sie im JDBC-Treiber clientseitig anfordern.

TCP-Keepalives sind viel besser als Validierungs-/Testabfragen, da sie viel weniger Aufwand verursachen und nicht zu unnötigem Log-Spam in den Server-Abfrageprotokollen führen.

20
Craig Ringer

Fügen Sie in Ihre Verbindungszeichenfolge auch den Port oder nur den Endpunkt ein? Versuchen Sie, den gesamten Endpunkt in Ihrer Verbindungszeichenfolge zu verwenden. Stellen Sie außerdem sicher, dass für die Sicherheitsgruppe, die der RDS-Instanz zugewiesen ist, die richtigen Ports und die eingehende CIDR definiert sind.

0
user2040074

Vielleicht versuchen

spring.datasource.validation-query=SELECT 1
spring.datasource.test-on-borrow=true

(Weitere Optionen finden Sie unter AbstractDataSourceConfiguration.)

0
Dave Syer