java.net.SocketException: No buffer space available (maximum connections reached?): connect 問題分析
阿新 • • 發佈:2018-11-18
- 異常日誌
Caused by: java.net.SocketException: No buffer space available (maximum connections reached?): connect
at java.net.TwoStacksPlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206 )
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121 )
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:326)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610 )
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
問題分析
網上說No buffer space available (maximum connections reached?)是因為機器埠號用盡導致tcp無法申請新的埠去建立連線。首先想到去檢視機器埠號使用情況。
大量的埠處於TIME_WAIT狀態,初步估計可能是客戶端每次去請求服務端都建立了一次tcp連線,使用完就關閉連線,但是tcp協議中如果客戶端主動關閉,為了確保傳送的報文不影響下一次連線,主動關閉的一方需要停留在TIME_WAIT狀態2*MSL(Max Segment Lifetime)。當併發高的時候,就會產生大量TIME_WAIT,而處於TIME_WAIT狀態的埠是不能馬上去建立新的連線的,這就導致No buffer space available (maximum connections reached?)這個異常。問題修復
排查程式碼發現有一處rest請求每次都會建立一個httpclient。相當於每次都要重新建立tcp連線,完成3次握手和4次揮手。
修復後的程式碼是使用http連線池,服用重複的http連線。這樣不必每次都去建立新的tcp連線。不僅可以避免埠被佔滿,也可以提升io的效能(tcp連線建立和關閉是需要開銷的)。httpclient提供PoolingHttpClientConnectionManager類支援http連線池的管理。