2015-01-14 1 views
0

이 코드는 기존 연결을 사용하는 대신 각 요청에 대해 RESTful 서버에 대한 새 연결을 만듭니다. 하나의 연결 만 있도록 코드를 어떻게 변경합니까?HttpClient : 서버에 단 하나의 연결을 갖는 방법?

"response = oClientCloseable.execute (...)"줄은 작업을 수행 할뿐만 아니라 연결을 생성합니다.

서버 데몬 로그를 검사했는데 유일한 활동은 .execute() 메소드에서 생성됩니다.

import org.apache.http.HttpResponse; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.config.RequestConfig; 
import org.apache.http.client.methods.HttpDelete; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.client.utils.HttpClientUtils; 
import org.apache.http.conn.ConnectionPoolTimeoutException; 
import org.apache.http.entity.StringEntity; 
import org.apache.http.impl.client.CloseableHttpClient; 
import org.apache.http.impl.client.HttpClientBuilder; 

... 

String pathPost = "http://someurl"; 
String pathDelete = "http://someurl2"; 
String xmlPost = "myxml"; 
HttpResponse response = null; 
BufferedReader rd = null; 
String line = null; 

CloseableHttpClient oClientCloseable = HttpClientBuilder.create().setDefaultRequestConfig(defaultRequestConfig).build(); 

for (int iLoop = 0; iLoop < 25; iLoop++) 
{ 
    HttpPost hPost = new HttpPost(pathPost); 
    hPost.setHeader("Content-Type", "application/xml"); 
    StringEntity se = new StringEntity(xmlPost); 
    hPost.setEntity(se); 
    line = ""; 
    try 
    { 
     response = oClientCloseable.execute(hPost); 
     rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
     while ((line = rd.readLine()) != null) 
     { 
      System.out.println(line); 
     } 
    } 
    catch (ClientProtocolException e) 
    { 
     e.printStackTrace(); 
    } 
    catch (ConnectionPoolTimeoutException e) 
    { 
     e.printStackTrace(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
    finally 
    { 
     HttpClientUtils.closeQuietly(response); 
    } 

    HttpDelete hDelete = new HttpDelete(pathDelete); 
    hDelete.setHeader("Content-Type", "application/xml"); 
    try 
    { 
     response = oClientCloseable.execute(hDelete); 
    } 
    catch (ClientProtocolException e) 
    { 
     e.printStackTrace(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
    finally 
    { 
     HttpClientUtils.closeQuietly(response); 
    } 
} 

oClientCloseable.close(); 

서버 데몬 로그는 연결할 때 무엇이든지간에 다음을 방출합니다. 이 응답에 묶어 (마감) 연결을 소모에 대해 이야기로

HTTP connection from [192.168.20.86]...ALLOWED 
POST [/linx] SIZE 248 
LINK-18446744073709551615: 2 SEND-BMQs, 2 RECV-BMQs 
THREAD-LINK_CONNECT-000, TID: 7F0F1B7FE700 READY 
NODE connecting to [192.168.30.20]:9099... 
LINK-0-CONTROL-NODE-0 connected to 192.168.30.20(192.168.30.20 IPv4 address: 192.168.30.20):9099 
Auth accepted, protocol compatible 
NODE connecting to [192.168.30.20]:9099... 

This article은 가장 관련성을 보인다. 이 기사는 consumeContent가 더 이상 사용되지 않으므로 오래된 것입니다. response.close()가 적절한 방법 인 것처럼 보이지만 연결이 닫히고 새로운 응답이 새로운 연결을 만듭니다.

필자는 serer 데몬에 대한 응답을 한 번 작성한 다음 조치 (get, post, put 또는 delete)를 변경해야하는 것으로 보입니다.

코드 변경 방법에 대한 생각? 나는 (미안하지 않도록 제대로 이름을 참조하는) 로버트 Rowntree의 제안을 구현

link 1 link 2 link 3

+0

['자바 HttpClient를 alive' 유지 (https://www.google.com/search?q=java%20httpclient%20keep%20alive) 나를 위해 트릭을하는 것처럼 보였다. 구체적으로이 링크 : [HttpClient 성능 최적화 가이드] (http://hc.apache.org/httpclient-3.x/performance.html) –

+1

"샘플의 최대 또는 최대 경로 제한"참조 ... https : // hc.apache.org/httpcomponents-client-4.3.x/httpclient/examples/org/apache/http/examples/client/ClientConfiguration.java –

답변

0

로 시작하는 코드를 대체하여 : 여기

내가 사용하는 다른 링크입니다

// Increase max total connection to 200 and increase default max connection per route to 20. 
// Configure total max or per route limits for persistent connections 
// that can be kept in the pool or leased by the connection manager. 
PoolingHttpClientConnectionManager oConnectionMgr = new PoolingHttpClientConnectionManager(); 
oConnectionMgr.setMaxTotal(200); 
oConnectionMgr.setDefaultMaxPerRoute(20); 
oConnectionMgr.setMaxPerRoute(new HttpRoute(new HttpHost("192.168.20.120", 8080)), 20); 

RequestConfig defaultRequestConfig = RequestConfig.custom() 
     .setSocketTimeout(5000) 
     .setConnectTimeout(5000) 
     .setConnectionRequestTimeout(5000) 
     .setStaleConnectionCheckEnabled(true) 
     .build(); 

//HttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(defaultRequestConfig).build(); 
CloseableHttpClient oClientCloseable = HttpClientBuilder.create() 
     .setConnectionManager(oConnectionMgr) 
     .setDefaultRequestConfig(defaultRequestConfig) 
     .build(); 

나는 여전히 인증 된 묶음을 보았다.

나는 공급 업체에 연락하여 수정 된 버전을 사용하여 로그를 공유했으며 코드는 깨끗합니다.

내 테스트 샘플은 원격 서버에 연결을 생성 한 다음 연결을 삭제하고 여러 번 반복합니다. 이 코드는 연결 생성 요청이 도착할 때마다 인증 메시지를 덤프합니다.

기술적으로 나는 서비스에 대한 새로운 RESTful 연결을 만드는 회선이 항상 "XXXXX 연결 허용됨"이라는 것을 이미 알고 있다는 것을 지적했습니다. 그 중 하나가있었습니다. 두 개의 링크가 브라우저 기반 인터페이스로 이동했기 때문에 나중에 모든 링크가 사라 졌는지 확인하십시오.

슬프게도, 나는 슬프지만 아파치 클라이언트를 사용할 수 있는지 확신하지 못한다. Apache는 GET 요청 내에서 메시지 본문을 지원하지 않습니다. 여기에 간단한 마음에 (나,이 경우), 아파치는 허용하지 않습니다

GET http://www.example.com/whatevermethod:myport?arg1=data1&arg2=data2 

아파치 HttpClient를 -> HttpGet가 setEntities 명령이 없습니다. 연구 결과에 따르면 POST 요청에 따라 서비스가 변경되고 변경되지 않을 것입니다.

0

당신은 확실히 아파치 HttpClient를에 쿼리 매개 변수를 사용할 수 있습니다

URIBuilder builder = new URIBuilder("http://www.example.com/whatevermehtod"); 
builder.addParameter("arg1", "data1"); 
URI uri = builder.build(); 
HttpGet get = new HttpGet(uri);