我在珠三角有一個問題。我們最近發布了一個 springboot 應用程式,它公開了 REST API。移動/網路 APP 呼叫 Spring 中的遺留 spring 應用程式 [不是 sprintboot],它是一個 web 應用程式,然后路由并呼叫新 springboot 中的這些失敗的 api。我們只看到這些 api 的超時例外。還有很多其他的 OUTBOUND api 呼叫從 spring 舊版 web 應用程式到其他應用程式,例如:登錄 API [apis 流量很大,但這些舊版 apis 運行良好并呼叫其他舊版應用程式。日志中沒有 例外/錯誤在公開了這些 REST API 的 springboot 應用程式中。事實上,我們只在 Spring Web 應用程式中看到超時 - 意味著連接已用盡,但這并不能解釋為什么其他使用相同包裝器 HTTPClient 的 apis OUTBOUND 呼叫沒有失敗。那些因超時而失敗的在 springboot 中沒有請求日志 [顯然是因為他們沒有離開 spring web 應用程式 tomcat JVM 并因超時而死在那里] 所以如果我們說連接池耗盡,其他大流量 OUTBOUnd 呼叫也應該面臨同樣的問題,但是我們沒有看到。所有 API 呼叫 OUTWARD 都使用 HTTPCLient [apache.] 不清楚是什么導致了問題。我還在服務器端的新 springboot 中明確定義了下面[我只是這樣做是為了看看這是否有區別但徒勞無功]:
server:
tomcat:
connection-timeout: 10s
max-connections: 20000
max-threads: 500
min-spare-threads: 10
在 spring 網路應用程式中的 tomcat 日志 [呼叫者]:
org.apache.http.conn.ConnectionPoolTimeoutException
org.apache.http.conn.ConnectionPoolTimeoutException.Timeout waiting for connection from pool
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:313)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:279)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:191)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:221)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:165)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:140)
at
任何輸入?
Wrapper HTTPClient 的代碼片段:
SSLContext sslContext = SSLContexts.createDefault();
HostnameVerifier hostnameVerifier = new DefaultHostnameVerifier();
SSLConnectionSocketFactory secureSSLConnectionSocketFactory = new SSLConnectionSocketFactory(
sslContext,
sslProtocolsArray,
ciphersArray,
hostnameVerifier);
ConnectionSocketFactory nonSecureConnectionSocketFactory = PlainConnectionSocketFactory.getSocketFactory();
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
.<ConnectionSocketFactory>create()
.register("https", secureSSLConnectionSocketFactory)
.register("http", nonSecureConnectionSocketFactory)
.build();
securePoolingConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
securePoolingConnectionManager.setMaxTotal(this.connectionMgrMaxTotalSecure);
securePoolingConnectionManager.setDefaultMaxPerRoute(this.connectionMgrMaxPerRouteSecure);
SocketConfig secureSocketConfig = SocketConfig
.custom()
.setSoKeepAlive(true)
.setTcpNoDelay(true)
.build();
secureHttpsClient = HttpClients
.custom()
.setSSLSocketFactory(secureSSLConnectionSocketFactory)
.setConnectionManager(securePoolingConnectionManager)
.setDefaultRequestConfig(secureRequestConfig)
.setDefaultSocketConfig(secureSocketConfig)
.disableAutomaticRetries()
.build();
Stacktrace after above is just failing at wrapper HTTPClient method where call is invoked :
protected String execute(HttpClient httpclient, HttpRequestBase http) throws IOException {
String result;
ResponseHandler<String> responseHandler = new BasicResponseHandler();
result = httpclient.execute(http, responseHandler);
return result;
}
uj5u.com熱心網友回復:
所以我必須挖掘另一個包裝器,它也使用了這個 HTTP 池,并且被用于我們正在泄漏的遺留檔案中。關閉這個。幸運的是,池統計 api 公開了,以便我可以看到確認泄漏的租用連接數。由于這第二個包裝器被重新使用并且我們在這個版本中使用過,這是可疑的,洗掉它解決了這個問題。挖掘那個包裝器并找出池是如何處理的但原因被發現是另一回事。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/317356.html
