在数据库连接闲置一段时间后,我的应用程序中出现以下异常:
... 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)
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.
我发现这个other question表明可以改善这种状况(超时现在需要更长时间),但是没有解决它。
我使用Spring Boot with JDBC(tomcat连接池)和JDBCTemplate。
是否有解决方法或修复方法? 也许强制连接池测试和重新连接? 我如何在这种环境中做到这一点?
编辑: 这是我的连接字符串
jdbc:postgresql://myhost.c2estvxozjm3.eu-west-1.rds.amazonaws.com/dashboard?tcpKeepAlive=true
解决方案:
根据所选答案中的建议编辑RDS服务器端TCP_KeepAlive参数。我使用的参数是:
tcp_keepalives_count 5
tcp_keepalives_idle 200
tcp_keepalives_interval 200
答案 0 :(得分:21)
它看起来像是某种东西 - 可能是你的NAT路由器,也许是AWS的终端 - 是连接跟踪,并且在一段时间后忘记了连接。
我建议enabling TCP keepalives。您可以在AWS RDS配置中启用它们服务器端;如果没有,您可以在JDBC驱动程序中请求客户端。
TCP keepalive比验证/测试查询要好得多,因为它们的开销要低得多,并且它们不会在服务器查询日志中导致不必要的日志垃圾邮件。
答案 1 :(得分:0)
也许试试
spring.datasource.validation-query=SELECT 1
spring.datasource.test-on-borrow=true
(有关其他选项,请参阅AbstractDataSourceConfiguration
。)
答案 2 :(得分:0)
在您的连接字符串中,您还包括端口还是仅包含端点?尝试在连接字符串中使用整个端点。还要检查以确保分配给RDS实例的安全组具有正确的端口和定义的入站CIDR。