2014-03-27 143 views
12

我得到了我的應用程序以下異常離開一定的時間數據庫連接空閒後:超時連接到Postgres數據庫在Amazon RDS從Azure的

... 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 

SOLUTION:

編輯爲所選答案提出的RDS服務器端TCP_KEEPALIVE參數。我使用的參數是:

tcp_keepalives_count  5 
tcp_keepalives_idle  200 
tcp_keepalives_interval 200 

回答

17

它看起來像什麼 - 也許一個NAT路由器上的結束,也許(其他選項參見AbstractDataSourceConfiguration)。 AWS的一些事情 - 連接跟蹤,並在一段時間後忘記連接。我建議enabling TCP keepalives。您可以在AWS RDS配置中啓用它們的服務器端;如果沒有,您可以在JDBC驅動程序中向客戶端請求它們。

TCP keepalive比驗證/測試查詢要好得多,因爲它們的開銷要低得多,並且它們不會在服務器查詢日誌中導致不必要的日誌垃圾郵件。

+1

這似乎解決了這個問題,因爲我在AWS postgres端添加了這些keepalive,我再也沒有超時了。我將刪除我嘗試過的其他東西(TCP內核中的keepalive,keepalive連接字符串和連接池上的連接驗證),並查看它是否自己保留。 –

+1

這解決了這個問題,我在RDS上使用的參數在編輯的問題上。 –

0

也許嘗試

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

+0

這種'解決'的問題,我在我的開發機器中沒有任何問題,但在我的服務器上(託管在Azure上),當我離開連接空閒時需要15分鐘才能得到響應。隨後的回覆將立即生效,直到我再次將連接閒置一段時間。除了規範之外,我的開發計算機和服務器之間的區別在於,我改變了TCP存儲設置的操作系統,如[本問題]中所述(http://stackoverflow.com/questions/20856599/mysql-ping-掛起與 - 亞馬遜RDS)。將嘗試在服務器上設置它。 –

+0

那裏沒有運氣,更改了Azure服務器上的TCPKeepAlive,但在連接閒置後仍然存在15米延遲問題。 –

+0

驗證查詢也導致大量日誌垃圾郵件,通常不是理想的,但有時您沒有多少選擇。 –

0

在你的連接字符串中你還包括端口還是隻包含端點?嘗試在連接字符串中使用整個端點。還要檢查以確保分配給RDS實例的安全組具有正確的端口和已定義的入站CIDR。

+0

將我的連接字符串添加到問題中(更改了主機名)。我能夠使用該字符串連接到數據庫,問題只發生在我將連接閒置一段時間之後 –

相關問題