データベース接続をしばらくアイドル状態にした後、アプリケーションで次の例外が発生します。
... 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.
私はこれを見つけました 他の質問 これは状況を改善する回避策を示唆しています(タイムアウトは今でははるかに長くかかります)が、それを修正しませんでした。
私は、JDBC(Tomcat接続プール)とJDBCTemplateでSpring Bootを使用しています。
回避策や修正はありますか?おそらく、接続プールにテストと再接続を強制しますか?この環境でどうすればよいですか?
編集:これは私の接続文字列です
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
それは何かのようです-多分NATルーター、多分AWSの側の何か)-接続追跡で、しばらくすると接続を忘れています.
有効にするTCPキープアライブ 。AWS RDS構成でサーバー側を有効にできる可能性があります。そうでない場合は、JDBCでクライアント側をリクエストできます運転者。
TCPキープアライブはオーバーヘッドがはるかに低く、サーバークエリログに不要なログスパムが発生しないため、検証/テストクエリよりもはるかに優れています。
接続文字列に、ポートまたはエンドポイントのみを含めていますか?接続文字列でエンドポイント全体を使用してみてください。また、RDSインスタンスに割り当てられたセキュリティグループに適切なポートと受信CIDRが定義されていることを確認してください。
多分試してみてください
spring.datasource.validation-query=SELECT 1
spring.datasource.test-on-borrow=true
(他のオプションについては、AbstractDataSourceConfiguration
を参照してください。)