這是本文件的舊版!
Connection Pool的Request Timeout沒有作用 (working..)
Problem
RestAPI的開發者,大都會非常頻繁的存取目標機器;Connection Pool是其中一個增進存取效率的方式。然而,這陣子在使用RESTEasy + Apache Connection Pool後,發現ConnectionRequestTimeout並沒作用。本篇文章主要分享目前的解決方法。
Version Info
因為相依libraries的限制,我們目前還沒使用最新版本的RESTEasy,資訊如下:
resteasy-client: 3.0.14.Final httpcore: 4.3.3 httpclient: 4.3.6
Test RESTClient
我寫了一個測試去確認ConnectionRequestTimeout是否有作用,方法如下:
- 將Pool大小設定為1。
- 設定ConnectionRequestTimeout為2秒。
- 依序發起兩個HTTP Get,但第一個請求不關閉。
- 接著發起第二個HTTP Get,由於沒有有效的連線可以使用,會Block。
- 在2秒後,Client會收到Exception,Root Cause為ConnectionPoolTimeoutException。
首先是HttpEngine設定的部分,由於這個版本ResteasyClientBuilder內建的PoolManager有些問題,因此我們是使用自己產生的,程式碼大致如下:
// 這使自己寫的Builder,產生的實體是PoolingHttpClientConnectionManager private HttpClientConnectionManager initConnectionManager(int poolSize, int perRoute) { HttpClientConnectionManagerBuilder builder = new HttpClientConnectionManagerBuilder(); return builder.withMaxTotal(poolSize).withDefaultMaxPerRoute(perRoute).build(); } @Test(timeout=20000) public void testRequestTimeoutWithCustomHttpEngine() throws Exception { int expectTimeout = 2*1000; connectionManager = initConnectionManager(20 , 1); RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(expectTimeout) .build(); ClientHttpEngine httpEngin = new ClientHttpEngineBuilder() .withRequestConfig(requestConfig) .withConnectionManager(connectionManager).build(); ResteasyClientBuilder clientBuilder = (ResteasyClientBuilder)ResteasyClientBuilder.newBuilder(); clientBuilder.httpEngine(httpEngin); // 以下略 }