从Azure连接到Amazon RDS上的Postgres数据库的超时

Cle*_*ves 17 postgresql spring-jdbc amazon-rds spring-boot

在数据库连接闲置一段时间后,我的应用程序中出现以下异常:

... 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)
Run Code Online (Sandbox Code Playgroud)

在psql中发生同样的问题我没有连接到本地数据库的问题,所以我很确定问题出在RDS上.

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.
Run Code Online (Sandbox Code Playgroud)

我发现了另一个问题,这个问题表明可以改善这种情况的工作(超时现在需要更长时间),但没有解决它.

我正在使用Spring Boot with JDBC(tomcat连接池)和JDBCTemplate.

有解决方法还是修复?也许强制连接池测试和重新连接?我如何在这种环境下做到这一点?

编辑:这是我的连接字符串

jdbc:postgresql://myhost.c2estvxozjm3.eu-west-1.rds.amazonaws.com/dashboard?tcpKeepAlive=true
Run Code Online (Sandbox Code Playgroud)

解:

根据所选答案中的建议编辑RDS服务器端TCP_KeepAlive参数.我正在使用的参数是:

tcp_keepalives_count      5
tcp_keepalives_idle     200
tcp_keepalives_interval 200
Run Code Online (Sandbox Code Playgroud)

Cra*_*ger 21

看起来像是某种东西 - 可能是你的NAT路由器,也许是AWS端的东西 - 是连接跟踪,并且在一段时间后忘记了连接.

我建议启用TCP Keepalive.您可以在AWS RDS配置中启用它们服务器端; 如果没有,您可以在JDBC驱动程序中请求客户端.

TCP keepalive比验证/测试查询好很多,因为它们的开销要低得多,并且它们不会在服务器查询日志中导致不必要的日志垃圾邮件.