2014-01-22 71 views
2

我對以下情況有點困惑。PostgresSQL前端意外關閉連接

我有一臺在主機A上運行的Postgres服務器,以及一臺在主機B上運行的基於Java的客戶機。客戶機使用org.postgresql.Driver JDBC驅動程序(版本9.1-901.jdbc3)。

有時在執行長時間運行的存儲過程時出現異常「java.net.SocketException: Socket closed」。我使用org.apache.commons.dbcp.BasicDataSource來檢索 連接。

DBCP池配置了默認選項。

我得到了tcp轉儲爲了找出哪邊(客戶端或服務器)套接字正在關閉;

這裏是我的本錢:

1. Client B sends a test query message when tries to borrow connection from dbcp pool ("Select 1") 
2. Server A sends successful response back (Type: Command completion, Ready for query) 
3. Client B sends ACK message in response on server A response (see the item 2). 
4. Client B sends query message to the server A. 
5. Server A sends ACK message in response on client Query message (see the item 4). 
6. Client B sends terminating message (Type : Termination) after some time passed (from 3 to 10 or sometimes even more minutes). 
7 Client B sends FIN ACK message to the server. 
8. Server A sends back ACK on termination message. 
9. Server A sends ACK on (FIN, ACK) message (item 7). 
10. Server A sends back a response on the client query (from item 4) Type: Row description Columns: 40. 
11. Client B sends RST message (reset). 
12. Server A continues sending response on the query Type: Data row Length: 438 Columns 40 and so on. 
13 Client B sends RST message (reset) again. 
14. Server A continues sending response on the query Type: Data row Length: 438 Columns 40 and so on. 
15. Client B sends RST message (reset). 

之後通信似乎是完成了。

項目6之後,在我的客戶端登錄我得到異常類似如下:

Caused by: java.net.SocketException: Socket closed 
     at java.net.SocketInputStream.socketRead0(Native Method) 
     at java.net.SocketInputStream.read(SocketInputStream.java:152) 
     at java.net.SocketInputStream.read(SocketInputStream.java:122) 
     at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:145) 
     at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:114) 
     at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:73) 
     at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:274) 
     at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1661) 
     at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257) 

能否請你幫我找出此類故障的原因。 (該錯誤每10次成功發生一次。)

在此先感謝!

+1

什麼,如果有的話,出現在PostgreSQL錯誤日誌中?考慮使用'log_min_messages = debug3'重新啓動PostgreSQL以獲取詳細的詳細(和巨大)日誌。你需要一個適當的'log_line_prefix',這樣你就可以知道哪個會話是哪個會話。另外,PostgreSQL版本? ('SELECT version()')。最後,客戶端和服務器之間的網絡是什麼樣的?多少跳?互聯網,還是隻有局域網?涉及WiFi?任何NAT,防火牆,代理,連接跟蹤路由器? –

回答

0

我們有類似的問題,它是由服務器和客戶端之間的防火牆或連接跟蹤路由器引起的。

我猜你在服務器端採取了tcpdump。查詢運行相當長的時間,連接上沒有流量。防火牆在打開的連接上有一個定時器;它到期並且防火牆關閉連接到服務器的連接,並返回到客戶端。在服務器端捕獲時,它看起來像客戶端正在關閉連接。

您可以通過在服務器端捕獲客戶端同時捕獲客戶端來驗證這一點 - 在客戶端,它看起來像服務器已關閉連接,而在服務器端,它看起來像服務器正在關閉連接。實際上,防火牆正在雙向關閉它。如果您的操作系統支持TCP Keepalive,您可以設置tcp_keepalives_idletcp_keepalives_interval和/或tcp_keepalives_count。或者,您將不得不更改防火牆上的設置。