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
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.
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.
Vielleicht versuchen
spring.datasource.validation-query=SELECT 1
spring.datasource.test-on-borrow=true
(Weitere Optionen finden Sie unter AbstractDataSourceConfiguration
.)